Re: [PATCH v3 1/2] target/s390x: report deprecated-props in cpu-model-expansion reply

2024-04-26 Thread Collin Walling
On 4/26/24 13:35, Collin Walling wrote:
> On 4/26/24 04:42, Markus Armbruster wrote:
>> Collin Walling  writes:
>>
>>> Retain a list of deprecated features disjoint from any particular
>>> CPU model. A query-cpu-model-expansion reply will now provide a list of
>>> properties (i.e. features) that are flagged as deprecated. Example:
>>>
>>> {
>>>   "return": {
>>> "model": {
>>>   "name": "z14.2-base",
>>>   "deprecated-props": [
>>> "bpb",
>>> "csske"
>>>   ],
>>>   "props": {
>>> "pfmfi": false,
>>> "exrl": true,
>>> ...a lot more props...
>>> "skey": false,
>>> "vxpdeh2": false
>>>   }
>>> }
>>>   }
>>> }
>>>
>>> It is recommended that s390 guests operate with these features
>>> explicitly disabled to ensure compatability with future hardware.
>>>
>>> Signed-off-by: Collin Walling 
>>> ---
>>>  qapi/machine-target.json |  5 -
>>>  target/s390x/cpu_features.c  | 14 ++
>>>  target/s390x/cpu_features.h  |  1 +
>>>  target/s390x/cpu_models_sysemu.c |  6 ++
>>>  4 files changed, 25 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>>> index 29e695aa06..3799a60e3d 100644
>>> --- a/qapi/machine-target.json
>>> +++ b/qapi/machine-target.json
>>> @@ -20,11 +20,14 @@
>>>  #
>>>  # @props: a dictionary of QOM properties to be applied
>>>  #
>>> +# @deprecated-props: a list of QOM properties that are flagged as 
>>> deprecated
>>
>> Deprecated by whom?  QEMU?  The CPU vendor?
>>
> 
> The CPU vendor would be the one who decides which props are deprecated.
> How about:
> 
> # @deprecated-props: a list of QOM properties that are flagged as
>deprecated by the CPU vendor
> 

^ let's ignore the incorrect indentation here.

Actually, I may be wildly incorrect with my description by referring to
this as "a list of QOM properties", when in fact this is just an array
of strings.  Also, the deprecated props may not always reflect the
features that are found by a static expansion, so I added another
sentence to describe that they are a part of a full model expansion.

# @deprecated-props: a list of properties that are flagged as deprecated
# by the CPU vendor.  These props are a subset of the model's full
# definition list of properties. (since X.Y)

I may need some help with the wording on the 2nd sentence.

[...]

> 
>>> +#
>>>  # Since: 2.8
>>>  ##
>>>  { 'struct': 'CpuModelInfo',
>>>'data': { 'name': 'str',
>>> -'*props': 'any' } }
>>> +'*props': 'any',
>>> +'*deprecated-props': ['str'] } }
>>>  
>>>  ##
>>>  # @CpuModelExpansionType:
>>
>> [...]
>>
>>
> 

-- 
Regards,
  Collin




Re: [PATCH v3 1/2] target/s390x: report deprecated-props in cpu-model-expansion reply

2024-04-26 Thread Collin Walling
On 4/26/24 13:45, David Hildenbrand wrote:
> On 26.04.24 19:44, David Hildenbrand wrote:
>> On 24.04.24 23:56, Collin Walling wrote:
>>> Retain a list of deprecated features disjoint from any particular
>>> CPU model. A query-cpu-model-expansion reply will now provide a list of
>>> properties (i.e. features) that are flagged as deprecated. Example:
>>>
>>>   {
>>> "return": {
>>>   "model": {
>>> "name": "z14.2-base",
>>> "deprecated-props": [
>>>   "bpb",
>>>   "csske"
>>> ],
>>> "props": {
>>>   "pfmfi": false,
>>>   "exrl": true,
>>>   ...a lot more props...
>>>   "skey": false,
>>>   "vxpdeh2": false
>>> }
>>>   }
>>> }
>>>   }
>>>
>>> It is recommended that s390 guests operate with these features
>>> explicitly disabled to ensure compatability with future hardware.
>>
>> Likely you should only report features that are applicable to a model.
>> that is, if it's part of the full_feat.
>>
>> Otherwise, the caller might simply want do set all features to "false",
>> and we'd fail setting a feature that is unknown to a specific CPU
>> generation.
>>
>> That is, you would AND the bitmap with the full_feat of the underlying
>> CPU definition.
> 
> Refreshing my memory, I think we can just clear any CPU features. We 
> only bail out when setting them!
> 

Very good point.  I've been working only with newer-gen machines and
would not have thought to test / catch that case.  I will filter the
deprecated-props array with features that are only available on the
full_model of the expanded CPU model.

-- 
Regards,
  Collin




Re: [PATCH v3 1/2] target/s390x: report deprecated-props in cpu-model-expansion reply

2024-04-26 Thread Collin Walling
On 4/26/24 04:42, Markus Armbruster wrote:
> Collin Walling  writes:
> 
>> Retain a list of deprecated features disjoint from any particular
>> CPU model. A query-cpu-model-expansion reply will now provide a list of
>> properties (i.e. features) that are flagged as deprecated. Example:
>>
>> {
>>   "return": {
>> "model": {
>>   "name": "z14.2-base",
>>   "deprecated-props": [
>> "bpb",
>> "csske"
>>   ],
>>   "props": {
>> "pfmfi": false,
>> "exrl": true,
>> ...a lot more props...
>> "skey": false,
>> "vxpdeh2": false
>>   }
>> }
>>   }
>> }
>>
>> It is recommended that s390 guests operate with these features
>> explicitly disabled to ensure compatability with future hardware.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  qapi/machine-target.json |  5 -
>>  target/s390x/cpu_features.c  | 14 ++
>>  target/s390x/cpu_features.h  |  1 +
>>  target/s390x/cpu_models_sysemu.c |  6 ++
>>  4 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>> index 29e695aa06..3799a60e3d 100644
>> --- a/qapi/machine-target.json
>> +++ b/qapi/machine-target.json
>> @@ -20,11 +20,14 @@
>>  #
>>  # @props: a dictionary of QOM properties to be applied
>>  #
>> +# @deprecated-props: a list of QOM properties that are flagged as deprecated
> 
> Deprecated by whom?  QEMU?  The CPU vendor?
> 

The CPU vendor would be the one who decides which props are deprecated.
How about:

# @deprecated-props: a list of QOM properties that are flagged as
 deprecated by the CPU vendor

> docs/devel/qapi-code-gen.rst:
> 
> For legibility, wrap text paragraphs so every line is at most 70
> characters long.
> 

Noted for next iteration.  Thank you.

>> +#
>>  # Since: 2.8
>>  ##
>>  { 'struct': 'CpuModelInfo',
>>'data': { 'name': 'str',
>> -'*props': 'any' } }
>> +'*props': 'any',
>> +'*deprecated-props': ['str'] } }
>>  
>>  ##
>>  # @CpuModelExpansionType:
> 
> [...]
> 
> 

-- 
Regards,
  Collin




Re: [PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-25 Thread Collin Walling
On 4/25/24 02:31, Markus Armbruster wrote:
> Collin Walling  writes:
> 
>> On 4/24/24 02:19, Markus Armbruster wrote:
>>> Collin Walling  writes:
>>>
>>>> This optional parameter for query-cpu-model-expansion enables CPU
>>>> model features flagged as deprecated to appear in the resulting
>>>> list of properties.
>>>>
>>>> This commit does not add support beyond adding a new argument
>>>> to the query. All queries with this option present will result
>>>> in an error claiming this option is not supported.
>>>>
>>>> Signed-off-by: Collin Walling 
>>>> ---
>>>>  qapi/machine-target.json | 7 ++-
>>>>  target/arm/arm-qmp-cmds.c| 7 +++
>>>>  target/i386/cpu-sysemu.c | 7 +++
>>>>  target/s390x/cpu_models_sysemu.c | 7 +++
>>>>  4 files changed, 27 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>>>> index 29e695aa06..b9da284d2d 100644
>>>> --- a/qapi/machine-target.json
>>>> +++ b/qapi/machine-target.json
>>>> @@ -285,6 +285,10 @@
>>>>  #
>>>>  # @type: expansion type, specifying how to expand the CPU model
>>>>  #
>>>> +# @disable-deprecated-feats: include CPU model features that are
>>>> +# flagged as deprecated. If supported, these features will appear
>>>> +# in the properties list paired with false.
>>>
>>> What's the default?
>>>
>>> Which command result(s) does this affect?  Suggest to explain using
>>> unabridged example QMP input and output before and after this series.
>>
>> Fair enough. Bool defaults to false but that's not apparent in the
>> description. I will add more detail.
> 
> I didn't mean to ask for example QMP in the doc comment.  I need you to
> explain the new member to me.  Once I understand what the thing does, I
> may have suggestions on improving the doc comment.
> 
> [...]
> 

Ah, I misunderstood.  The idea behind this "disable-deprecated-feats"
option is to add/override any CPU features that are flagged as
deprecated to the props dictionary (found in the CpuModelInfo struct)
paired with the value false.

For example, the csske feature on s390x is flagged as deprecated.  If a
query-cpu-model-expansion command is created with
"disable-deprecated-feats": true, then the csske feature will show up in
the props list as "csske": false.  This also overrides any user defined
features and props that would show up in the response normally. E.g. if
the same command was executed and "csske": true was provided in the
model's properties by the user, the response will still show "csske":
false since the "disable-deprecated-feats" option takes priority (there
is a discussion with David H regarding which should take precedence --
this is a flaw in this design).

In the below QMP samples I provide a static expansion on a host model.
Pay close attention to the bpb, te, cte, and csske properties.


 Before


This is how query-cpu-model-expansion may be executed today:

{
  "execute": "query-cpu-model-expansion",
  "arguments": {
"type": "static",
"model": {
  "name": "host"
}
  }
}

{
  "return": {
"model": {
  "name": "z14.2-base",
  "props": {
"aen": true,
"cmmnt": true,
"aefsi": true,
"diag318": true,
"mepoch": true,
"msa8": true,
"msa7": true,
"msa6": true,
"msa5": true,
"msa4": true,
"msa3": true,
"msa2": true,
"msa1": true,
"sthyi": true,
"edat": true,
"ri": true,
"edat2": true,
"etoken": true,
"vx": true,
"ipter": true,
"mepochptff": true,
"ap": true,
"vxeh": true,
"vxpd": true,
"esop": true,
"apqi": true,
"apft": true,
"els": true,
"iep": true,
"apqci": true,
"cte": true,<--
"ais": true,
"bpb": true,<--
"ctop": true,
"gs": true,
"ppa15": true,
"z

Re: [PATCH v2 2/3] target/s390x: add support for "disable-deprecated-feats" expansion option

2024-04-25 Thread Collin Walling
On 4/25/24 04:10, David Hildenbrand wrote:
> On 24.04.24 20:33, Collin Walling wrote:
>> On 4/24/24 03:24, David Hildenbrand wrote:
>>> On 23.04.24 23:06, Collin Walling wrote:
>>>> Retain a list of deprecated features disjoint from any particular
>>>> CPU model. When a query-cpu-model-expansion is provided with the
>>>> "disable-deprecated-feats" option set, the resulting properties list
>>>> will include all deprecated features paired with false. Example:
>>>>
>>>>{ ... "bpb": false, "csske": false, ...}
>>>>
>>>> It is recommended that s390 guests operate with these features
>>>> explicitly disabled to ensure compatability with future hardware.
>>>>
>>>> Signed-off-by: Collin Walling 
>>>> ---
>>>>target/s390x/cpu_features.c  | 14 ++
>>>>target/s390x/cpu_features.h  |  1 +
>>>>target/s390x/cpu_models_sysemu.c | 20 
>>>>3 files changed, 27 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
>>>> index d28eb65845..efafc9711c 100644
>>>> --- a/target/s390x/cpu_features.c
>>>> +++ b/target/s390x/cpu_features.c
>>>> @@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap 
>>>> features, void *opaque,
>>>>};
>>>>}
>>>>
>>>> +void s390_get_deprecated_features(S390FeatBitmap features)
>>>> +{
>>>> +static const int feats[] = {
>>>> + /* CSSKE is deprecated on newer generations */
>>>> + S390_FEAT_CONDITIONAL_SSKE,
>>>> + S390_FEAT_BPB,
>>>> +};
>>>> +int i;
>>>> +
>>>> +for (i = 0; i < ARRAY_SIZE(feats); i++) {
>>>> +set_bit(feats[i], features);
>>>> +}
>>>> +}
>>>> +
>>>>#define FEAT_GROUP_INIT(_name, _group, _desc)\
>>>>{\
>>>>.name = _name,   \
>>>> diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
>>>> index a9bd68a2e1..661a8cd6db 100644
>>>> --- a/target/s390x/cpu_features.h
>>>> +++ b/target/s390x/cpu_features.h
>>>> @@ -69,6 +69,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, 
>>>> S390FeatType type,
>>>>  uint8_t *data);
>>>>void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void 
>>>> *opaque,
>>>>   void (*fn)(const char *name, void 
>>>> *opaque));
>>>> +void s390_get_deprecated_features(S390FeatBitmap features);
>>>>
>>>>/* Definition of a CPU feature group */
>>>>typedef struct {
>>>> diff --git a/target/s390x/cpu_models_sysemu.c 
>>>> b/target/s390x/cpu_models_sysemu.c
>>>> index ef9fa80efd..b002819188 100644
>>>> --- a/target/s390x/cpu_models_sysemu.c
>>>> +++ b/target/s390x/cpu_models_sysemu.c
>>>> @@ -171,7 +171,8 @@ static void qdict_add_enabled_feat(const char *name, 
>>>> void *opaque)
>>>>
>>>>/* convert S390CPUDef into a static CpuModelInfo */
>>>>static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel 
>>>> *model,
>>>> -bool delta_changes)
>>>> +bool delta_changes,
>>>> +bool disable_deprecated_feats)
>>>>{
>>>>QDict *qdict = qdict_new();
>>>>S390FeatBitmap bitmap;
>>>> @@ -201,6 +202,13 @@ static void cpu_info_from_model(CpuModelInfo *info, 
>>>> const S390CPUModel *model,
>>>>s390_feat_bitmap_to_ascii(bitmap, qdict, 
>>>> qdict_add_disabled_feat);
>>>>}
>>>>
>>>> +/* features flagged as deprecated */
>>>> +if (disable_deprecated_feats) {
>>>> +bitmap_zero(bitmap, S390_FEAT_MAX);
>>>> +s390_get_deprecated_features(bitmap);
>>>> +s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
>>>> +}
>>>
>>> Likely, we should remove these features from the actual bitm

Re: [PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-25 Thread Collin Walling
On 4/25/24 09:35, Daniel P. Berrangé wrote:
> On Wed, Apr 24, 2024 at 03:12:42PM -0400, Collin Walling wrote:
>> On 4/24/24 13:51, Collin Walling wrote:
>>> On 4/24/24 04:20, Daniel P. Berrangé wrote:
>>>> On Tue, Apr 23, 2024 at 05:06:53PM -0400, Collin Walling wrote:
>>>>> This optional parameter for query-cpu-model-expansion enables CPU
>>>>> model features flagged as deprecated to appear in the resulting
>>>>> list of properties.
>>>>>
>>>>> This commit does not add support beyond adding a new argument
>>>>> to the query. All queries with this option present will result
>>>>> in an error claiming this option is not supported.
>>>>>
>>>>> Signed-off-by: Collin Walling 
>>>>> ---
>>>>>  qapi/machine-target.json | 7 ++-
>>>>>  target/arm/arm-qmp-cmds.c| 7 +++
>>>>>  target/i386/cpu-sysemu.c | 7 +++
>>>>>  target/s390x/cpu_models_sysemu.c | 7 +++
>>>>>  4 files changed, 27 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>>>>> index 29e695aa06..b9da284d2d 100644
>>>>> --- a/qapi/machine-target.json
>>>>> +++ b/qapi/machine-target.json
>>>>> @@ -285,6 +285,10 @@
>>>>>  #
>>>>>  # @type: expansion type, specifying how to expand the CPU model
>>>>>  #
>>>>> +# @disable-deprecated-feats: include CPU model features that are
>>>>> +# flagged as deprecated. If supported, these features will appear
>>>>> +# in the properties list paired with false.
>>>>> +#
>>>>>  # Returns: a CpuModelExpansionInfo describing the expanded CPU model
>>>>>  #
>>>>>  # Errors:
>>>>> @@ -298,7 +302,8 @@
>>>>>  ##
>>>>>  { 'command': 'query-cpu-model-expansion',
>>>>>'data': { 'type': 'CpuModelExpansionType',
>>>>> -'model': 'CpuModelInfo' },
>>>>> +'model': 'CpuModelInfo',
>>>>> +'*disable-deprecated-feats': 'bool' },
>>>>>'returns': 'CpuModelExpansionInfo',
>>>>>'if': { 'any': [ 'TARGET_S390X',
>>>>> 'TARGET_I386',
>>>>
>>>> I think this is an odd design approach. Lets consider the
>>>> current output:
>>>>
>>>> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
>>>> {
>>>> "return": {
>>>> "model": {
>>>> "name": "z14-base",
>>>> "props": {
>>>> "aefsi": true,
>>>> "aen": true,
>>>> ...snip...
>>>> "vxpd": true,
>>>> "zpci": true
>>>> }
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>> If we want to inform a mgmt app of some features being deprecated,
>>>> why not just unconditionally include that info in the reply thus:
>>>>
>>>>
>>>> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
>>>> {
>>>> "return": {
>>>> "model": {
>>>> "name": "z14-base",
>>>> "props": {
>>>> "aefsi": true,
>>>> "aen": true,
>>>> ...snip...
>>>> "vxpd": true,
>>>> "zpci": true
>>>> }
>>>> "deprecated-props": ["ppa15", "ri"]
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>>
>>>> With regards,
>>>> Daniel
>>>
>>> That's a good idea. In this way, we're not mucking up any of the CPU
>>> model information and this makes it much more clear as to which features
>>> are actually deprecated... I like this more.
>>>
>>> I'll work on this.
>>>
>>
>> Follow-up question as I look more closely to the QMP response data
>> structures: should the "deprecated-props" list be added to the
>> CpuModelInfo struct, or to the CpuModelExpansionInfo struct?
>>
>> The former makes more sense to me, as the deprecated features are tied
>> to the actual CPU model... but unsure if other QMP commands would even
>> care about this info? I will begin with this approach, and if feedback
>> in the interim strongly sways in the other direction, then it should be
>> an easy change :)
> 
> I hink CpuModelInfo makes more sense than CpuModelExpansionInfo.
> The CpuModelExpansionInfo struct feels pretty pointless to me
> in fact, since the only thing it contains is CpuModelInfo !
> 

Agreed! :)

> I think it should also be added to 'CpuDefinitionInfo', which
> is the return type of 'query-cpu-defintions'.  This command already
> has a 'unavailable-features' array listing features which the host
> does not support. Conceptually having a 'deprecated-features' array
> alongside that is a nice fit.
> 

Okay. Pending review on the v3 I posted yesterday -- if those patches
look like they're on the right track, then I can add this
"deprecated-props" array to CpuDefinitionInfo as well for the next
iteration.

> 
> 
> With regards,
> Daniel

-- 
Regards,
  Collin




[PATCH v3 2/2] target/s390x: flag te and cte as deprecated

2024-04-24 Thread Collin Walling
Add the CONSTRAINT_TRANSACTIONAL_EXE (cte) and TRANSACTIONAL_EXE (te)
to the list of deprecated features.

Signed-off-by: Collin Walling 
---
 target/s390x/cpu_features.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index efafc9711c..cb4e2b8920 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -218,6 +218,9 @@ void s390_get_deprecated_features(S390FeatBitmap features)
  /* CSSKE is deprecated on newer generations */
  S390_FEAT_CONDITIONAL_SSKE,
  S390_FEAT_BPB,
+ /* Deprecated on z16 */
+ S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+ S390_FEAT_TRANSACTIONAL_EXE
 };
 int i;
 
-- 
2.43.0




[PATCH v3 1/2] target/s390x: report deprecated-props in cpu-model-expansion reply

2024-04-24 Thread Collin Walling
Retain a list of deprecated features disjoint from any particular
CPU model. A query-cpu-model-expansion reply will now provide a list of
properties (i.e. features) that are flagged as deprecated. Example:

{
  "return": {
"model": {
  "name": "z14.2-base",
  "deprecated-props": [
"bpb",
"csske"
  ],
  "props": {
"pfmfi": false,
"exrl": true,
...a lot more props...
"skey": false,
"vxpdeh2": false
  }
}
  }
}

It is recommended that s390 guests operate with these features
explicitly disabled to ensure compatability with future hardware.

Signed-off-by: Collin Walling 
---
 qapi/machine-target.json |  5 -
 target/s390x/cpu_features.c  | 14 ++
 target/s390x/cpu_features.h  |  1 +
 target/s390x/cpu_models_sysemu.c |  6 ++
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 29e695aa06..3799a60e3d 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -20,11 +20,14 @@
 #
 # @props: a dictionary of QOM properties to be applied
 #
+# @deprecated-props: a list of QOM properties that are flagged as deprecated
+#
 # Since: 2.8
 ##
 { 'struct': 'CpuModelInfo',
   'data': { 'name': 'str',
-'*props': 'any' } }
+'*props': 'any',
+'*deprecated-props': ['str'] } }
 
 ##
 # @CpuModelExpansionType:
diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index d28eb65845..efafc9711c 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap 
features, void *opaque,
 };
 }
 
+void s390_get_deprecated_features(S390FeatBitmap features)
+{
+static const int feats[] = {
+ /* CSSKE is deprecated on newer generations */
+ S390_FEAT_CONDITIONAL_SSKE,
+ S390_FEAT_BPB,
+};
+int i;
+
+for (i = 0; i < ARRAY_SIZE(feats); i++) {
+set_bit(feats[i], features);
+}
+}
+
 #define FEAT_GROUP_INIT(_name, _group, _desc)\
 {\
 .name = _name,   \
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index a9bd68a2e1..661a8cd6db 100644
--- a/target/s390x/cpu_features.h
+++ b/target/s390x/cpu_features.h
@@ -69,6 +69,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, 
S390FeatType type,
   uint8_t *data);
 void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque));
+void s390_get_deprecated_features(S390FeatBitmap features);
 
 /* Definition of a CPU feature group */
 typedef struct {
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 2d99218069..307e3885f4 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -206,6 +206,12 @@ static void cpu_info_from_model(CpuModelInfo *info, const 
S390CPUModel *model,
 } else {
 info->props = QOBJECT(qdict);
 }
+
+bitmap_zero(bitmap, S390_FEAT_MAX);
+s390_get_deprecated_features(bitmap);
+s390_feat_bitmap_to_ascii(bitmap, >deprecated_props,
+  list_add_feat);
+info->has_deprecated_props = !!info->deprecated_props;
 }
 
 CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType 
type,
-- 
2.43.0




Re: [PATCH v3 0/2] query-cpu-model-expansion: report deprecated features

2024-04-24 Thread Collin Walling
On 4/24/24 17:56, Collin Walling wrote:

> 
> Check patch #2 description for an example output.
> 

I meant patch #1, sorry. Forgot I dropped a patch in this series.

-- 
Regards,
  Collin




[PATCH v3 0/2] query-cpu-model-expansion: report deprecated features

2024-04-24 Thread Collin Walling
Previous version here (different subject line): 
https://mail.gnu.org/archive/html/qemu-devel/2024-04/msg03200.html

Changelog

v3
- removed optional disable-deprecated-feats argument
- added deprecated-props array to CpuModelInfo struct
- amended cover letter language to reflect design

v2 
- removed "static-recommended" expansion type
- implemented optional disable-deprecated-feats argument

---

The current implementation of query-cpu-model-expansion is lacking a way to 
retrieve
CPU models with properties (i.e. features) that are flagged as deprecated. To 
remedy
this, a list of deprecated-props has been appended to the CpuModelInfo struct, 
and
will currently be reported by a query-cpu-model-expansion.

Check patch #2 description for an example output.

A simple interface is designed that contains an array of feature bits that are 
flagged
as deprecated. This list may be easily populated with more features in the 
future.

void s390_get_deprecated_features(S390FeatBitmap features)
{
static const int feats[] = {
 /* CSSKE is deprecated on newer generations */
 S390_FEAT_CONDITIONAL_SSKE,
 S390_FEAT_BPB,
 /* Deprecated on z16 */
 S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
 S390_FEAT_TRANSACTIONAL_EXE
};
int i;

for (i = 0; i < ARRAY_SIZE(feats); i++) {
set_bit(feats[i], features);
}
}

Use case example:

Newer s390 machines may signal the end-of-support for particular CPU features,
rendering guests operating with older CPU models incapable of running on
said machines. A manual effort to disable certain CPU features would be
required.

Reporting a list of deprecated features allows the user / management app to
take the next steps to ensure the guest is defined in a way that ensures
a migration in the future.

Collin L. Walling (2):
  target/s390x: report deprecated-props in cpu-model-expansion reply
  target/s390x: flag te and cte as deprecated

 qapi/machine-target.json |  5 -
 target/s390x/cpu_features.c  | 17 +
 target/s390x/cpu_features.h  |  1 +
 target/s390x/cpu_models_sysemu.c |  6 ++
 4 files changed, 28 insertions(+), 1 deletion(-)

-- 
2.43.0




Re: [PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-24 Thread Collin Walling
On 4/24/24 13:51, Collin Walling wrote:
> On 4/24/24 04:20, Daniel P. Berrangé wrote:
>> On Tue, Apr 23, 2024 at 05:06:53PM -0400, Collin Walling wrote:
>>> This optional parameter for query-cpu-model-expansion enables CPU
>>> model features flagged as deprecated to appear in the resulting
>>> list of properties.
>>>
>>> This commit does not add support beyond adding a new argument
>>> to the query. All queries with this option present will result
>>> in an error claiming this option is not supported.
>>>
>>> Signed-off-by: Collin Walling 
>>> ---
>>>  qapi/machine-target.json | 7 ++-
>>>  target/arm/arm-qmp-cmds.c| 7 +++
>>>  target/i386/cpu-sysemu.c | 7 +++
>>>  target/s390x/cpu_models_sysemu.c | 7 +++
>>>  4 files changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>>> index 29e695aa06..b9da284d2d 100644
>>> --- a/qapi/machine-target.json
>>> +++ b/qapi/machine-target.json
>>> @@ -285,6 +285,10 @@
>>>  #
>>>  # @type: expansion type, specifying how to expand the CPU model
>>>  #
>>> +# @disable-deprecated-feats: include CPU model features that are
>>> +# flagged as deprecated. If supported, these features will appear
>>> +# in the properties list paired with false.
>>> +#
>>>  # Returns: a CpuModelExpansionInfo describing the expanded CPU model
>>>  #
>>>  # Errors:
>>> @@ -298,7 +302,8 @@
>>>  ##
>>>  { 'command': 'query-cpu-model-expansion',
>>>'data': { 'type': 'CpuModelExpansionType',
>>> -'model': 'CpuModelInfo' },
>>> +'model': 'CpuModelInfo',
>>> +'*disable-deprecated-feats': 'bool' },
>>>'returns': 'CpuModelExpansionInfo',
>>>'if': { 'any': [ 'TARGET_S390X',
>>> 'TARGET_I386',
>>
>> I think this is an odd design approach. Lets consider the
>> current output:
>>
>> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
>> {
>> "return": {
>> "model": {
>> "name": "z14-base",
>> "props": {
>> "aefsi": true,
>> "aen": true,
>> ...snip...
>> "vxpd": true,
>> "zpci": true
>> }
>> }
>> }
>> }
>>
>>
>> If we want to inform a mgmt app of some features being deprecated,
>> why not just unconditionally include that info in the reply thus:
>>
>>
>> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
>> {
>> "return": {
>> "model": {
>> "name": "z14-base",
>> "props": {
>> "aefsi": true,
>> "aen": true,
>> ...snip...
>> "vxpd": true,
>> "zpci": true
>> }
>> "deprecated-props": ["ppa15", "ri"]
>> }
>> }
>> }
>>
>>
>>
>> With regards,
>> Daniel
> 
> That's a good idea. In this way, we're not mucking up any of the CPU
> model information and this makes it much more clear as to which features
> are actually deprecated... I like this more.
> 
> I'll work on this.
> 

Follow-up question as I look more closely to the QMP response data
structures: should the "deprecated-props" list be added to the
CpuModelInfo struct, or to the CpuModelExpansionInfo struct?

The former makes more sense to me, as the deprecated features are tied
to the actual CPU model... but unsure if other QMP commands would even
care about this info? I will begin with this approach, and if feedback
in the interim strongly sways in the other direction, then it should be
an easy change :)

-- 
Regards,
  Collin




Re: [PATCH v2 2/3] target/s390x: add support for "disable-deprecated-feats" expansion option

2024-04-24 Thread Collin Walling
On 4/24/24 03:24, David Hildenbrand wrote:
> On 23.04.24 23:06, Collin Walling wrote:
>> Retain a list of deprecated features disjoint from any particular
>> CPU model. When a query-cpu-model-expansion is provided with the
>> "disable-deprecated-feats" option set, the resulting properties list
>> will include all deprecated features paired with false. Example:
>>
>>  { ... "bpb": false, "csske": false, ...}
>>
>> It is recommended that s390 guests operate with these features
>> explicitly disabled to ensure compatability with future hardware.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>   target/s390x/cpu_features.c  | 14 ++
>>   target/s390x/cpu_features.h  |  1 +
>>   target/s390x/cpu_models_sysemu.c | 20 
>>   3 files changed, 27 insertions(+), 8 deletions(-)
>>
>> diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
>> index d28eb65845..efafc9711c 100644
>> --- a/target/s390x/cpu_features.c
>> +++ b/target/s390x/cpu_features.c
>> @@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap 
>> features, void *opaque,
>>   };
>>   }
>>   
>> +void s390_get_deprecated_features(S390FeatBitmap features)
>> +{
>> +static const int feats[] = {
>> + /* CSSKE is deprecated on newer generations */
>> + S390_FEAT_CONDITIONAL_SSKE,
>> + S390_FEAT_BPB,
>> +};
>> +int i;
>> +
>> +for (i = 0; i < ARRAY_SIZE(feats); i++) {
>> +set_bit(feats[i], features);
>> +}
>> +}
>> +
>>   #define FEAT_GROUP_INIT(_name, _group, _desc)\
>>   {\
>>   .name = _name,   \
>> diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
>> index a9bd68a2e1..661a8cd6db 100644
>> --- a/target/s390x/cpu_features.h
>> +++ b/target/s390x/cpu_features.h
>> @@ -69,6 +69,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, 
>> S390FeatType type,
>> uint8_t *data);
>>   void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
>>  void (*fn)(const char *name, void *opaque));
>> +void s390_get_deprecated_features(S390FeatBitmap features);
>>   
>>   /* Definition of a CPU feature group */
>>   typedef struct {
>> diff --git a/target/s390x/cpu_models_sysemu.c 
>> b/target/s390x/cpu_models_sysemu.c
>> index ef9fa80efd..b002819188 100644
>> --- a/target/s390x/cpu_models_sysemu.c
>> +++ b/target/s390x/cpu_models_sysemu.c
>> @@ -171,7 +171,8 @@ static void qdict_add_enabled_feat(const char *name, 
>> void *opaque)
>>   
>>   /* convert S390CPUDef into a static CpuModelInfo */
>>   static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel 
>> *model,
>> -bool delta_changes)
>> +bool delta_changes,
>> +bool disable_deprecated_feats)
>>   {
>>   QDict *qdict = qdict_new();
>>   S390FeatBitmap bitmap;
>> @@ -201,6 +202,13 @@ static void cpu_info_from_model(CpuModelInfo *info, 
>> const S390CPUModel *model,
>>   s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
>>   }
>>   
>> +/* features flagged as deprecated */
>> +if (disable_deprecated_feats) {
>> +bitmap_zero(bitmap, S390_FEAT_MAX);
>> +s390_get_deprecated_features(bitmap);
>> +s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
>> +}
> 
> Likely, we should remove these features from the actual bitmap, such 
> that they won't appear twice in the output? I'd expect the 
> cpu_info_from_model() caller to handle that.
> 
> Just adding them to the list as disabled is likely wrong.
> 
> For example, if someone were to expend a given model with "... bpb: 
> true" with disable-deprecated-feat=on, that should be remove from 
> "bpb:true", and only replaced by "bpb=false" if it would be part of the 
> CPU model we would be expanding to.
> 
> Or am I missing something?
> 

qdict_add_disabled_feat will handle updating the feature if it already
exists. I placed the code to process deprecated features as the last
step of cpu_info_from_model to override any features that have already
been added to the bitmap. Whether it should be the deprecated feats that
take priority, or what the user requests is up in the air, however...

... Daniel's suggestion to modify the QMP response to include a separate
list of "deprecated-props" seems like a much more efficient and readable
way that alleviates both your and Markus' concerns.

Thanks for your feedback! Will work on the next proposal that implements
the above. If you have any strong suggestions otherwise, please let me
know :)

-- 
Regards,
  Collin




Re: [PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-24 Thread Collin Walling
On 4/24/24 04:20, Daniel P. Berrangé wrote:
> On Tue, Apr 23, 2024 at 05:06:53PM -0400, Collin Walling wrote:
>> This optional parameter for query-cpu-model-expansion enables CPU
>> model features flagged as deprecated to appear in the resulting
>> list of properties.
>>
>> This commit does not add support beyond adding a new argument
>> to the query. All queries with this option present will result
>> in an error claiming this option is not supported.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  qapi/machine-target.json | 7 ++-
>>  target/arm/arm-qmp-cmds.c| 7 +++
>>  target/i386/cpu-sysemu.c | 7 +++
>>  target/s390x/cpu_models_sysemu.c | 7 +++
>>  4 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>> index 29e695aa06..b9da284d2d 100644
>> --- a/qapi/machine-target.json
>> +++ b/qapi/machine-target.json
>> @@ -285,6 +285,10 @@
>>  #
>>  # @type: expansion type, specifying how to expand the CPU model
>>  #
>> +# @disable-deprecated-feats: include CPU model features that are
>> +# flagged as deprecated. If supported, these features will appear
>> +# in the properties list paired with false.
>> +#
>>  # Returns: a CpuModelExpansionInfo describing the expanded CPU model
>>  #
>>  # Errors:
>> @@ -298,7 +302,8 @@
>>  ##
>>  { 'command': 'query-cpu-model-expansion',
>>'data': { 'type': 'CpuModelExpansionType',
>> -'model': 'CpuModelInfo' },
>> +'model': 'CpuModelInfo',
>> +'*disable-deprecated-feats': 'bool' },
>>'returns': 'CpuModelExpansionInfo',
>>'if': { 'any': [ 'TARGET_S390X',
>> 'TARGET_I386',
> 
> I think this is an odd design approach. Lets consider the
> current output:
> 
> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
> {
> "return": {
> "model": {
> "name": "z14-base",
> "props": {
> "aefsi": true,
> "aen": true,
> ...snip...
> "vxpd": true,
> "zpci": true
> }
> }
> }
> }
> 
> 
> If we want to inform a mgmt app of some features being deprecated,
> why not just unconditionally include that info in the reply thus:
> 
> 
> (QEMU) query-cpu-model-expansion type=static model={"name":"z14"}
> {
> "return": {
> "model": {
> "name": "z14-base",
> "props": {
> "aefsi": true,
> "aen": true,
> ...snip...
> "vxpd": true,
> "zpci": true
> }
> "deprecated-props": ["ppa15", "ri"]
> }
> }
> }
> 
> 
> 
> With regards,
> Daniel

That's a good idea. In this way, we're not mucking up any of the CPU
model information and this makes it much more clear as to which features
are actually deprecated... I like this more.

I'll work on this.

-- 
Regards,
  Collin




Re: [PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-24 Thread Collin Walling
On 4/24/24 02:19, Markus Armbruster wrote:
> Collin Walling  writes:
> 
>> This optional parameter for query-cpu-model-expansion enables CPU
>> model features flagged as deprecated to appear in the resulting
>> list of properties.
>>
>> This commit does not add support beyond adding a new argument
>> to the query. All queries with this option present will result
>> in an error claiming this option is not supported.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  qapi/machine-target.json | 7 ++-
>>  target/arm/arm-qmp-cmds.c| 7 +++
>>  target/i386/cpu-sysemu.c | 7 +++
>>  target/s390x/cpu_models_sysemu.c | 7 +++
>>  4 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>> index 29e695aa06..b9da284d2d 100644
>> --- a/qapi/machine-target.json
>> +++ b/qapi/machine-target.json
>> @@ -285,6 +285,10 @@
>>  #
>>  # @type: expansion type, specifying how to expand the CPU model
>>  #
>> +# @disable-deprecated-feats: include CPU model features that are
>> +# flagged as deprecated. If supported, these features will appear
>> +# in the properties list paired with false.
> 
> What's the default?
> 
> Which command result(s) does this affect?  Suggest to explain using
> unabridged example QMP input and output before and after this series.
> 

Fair enough. Bool defaults to false but that's not apparent in the
description. I will add more detail.

> We generally avoid abbreviations in QMP names.  Let's call this
> @disable-deprecated-features.
> 

Okay.

> Separate sentences with two spaces for consistency, please.
> 

Understood.

>> +#
>>  # Returns: a CpuModelExpansionInfo describing the expanded CPU model
>>  #
>>  # Errors:
>> @@ -298,7 +302,8 @@
>>  ##
>>  { 'command': 'query-cpu-model-expansion',
>>'data': { 'type': 'CpuModelExpansionType',
>> -'model': 'CpuModelInfo' },
>> +'model': 'CpuModelInfo',
>> +'*disable-deprecated-feats': 'bool' },
>>'returns': 'CpuModelExpansionInfo',
>>'if': { 'any': [ 'TARGET_S390X',
>> 'TARGET_I386',
>   'TARGET_ARM',
>   'TARGET_LOONGARCH64',
>   'TARGET_RISCV' ] } }
> 
> Put a pin into this conditional: [*].
> 
>> diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
>> index 3cc8cc738b..1010d654e3 100644
>> --- a/target/arm/arm-qmp-cmds.c
>> +++ b/target/arm/arm-qmp-cmds.c
>> @@ -100,6 +100,8 @@ static const char *cpu_model_advertised_features[] = {
>>  
>>  CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType 
>> type,
>>   CpuModelInfo *model,
>> + bool 
>> has_disable_deprecated_feats,
>> + bool 
>> disable_deprecated_feats,
>>   Error **errp)
>>  {
>>  CpuModelExpansionInfo *expansion_info;
>> @@ -110,6 +112,11 @@ CpuModelExpansionInfo 
>> *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>>  const char *name;
>>  int i;
>>  
>> +if (has_disable_deprecated_feats) {
>> +error_setg(, "Unsupported option 'disable-deprecated-feats'");
>> +return NULL;
>> +}
> 
> Reject the new argument in the ARM version, ...
> 
>> +
>>  if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
>>  error_setg(errp, "The requested expansion type is not supported");
>>  return NULL;
>> diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
>> index 3f9093d285..c15786fb66 100644
>> --- a/target/i386/cpu-sysemu.c
>> +++ b/target/i386/cpu-sysemu.c
>> @@ -196,6 +196,8 @@ out:
>>  CpuModelExpansionInfo *
>>  qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>>CpuModelInfo *model,
>> +  bool 
>> has_disable_deprecated_feats,
>> +  bool 
>> disable_deprecated_feats,
>>Error **errp)
>>  {
>>  X86CPU *xc = NULL;
>> @@ -204,6 +206,11 @@ qmp_query_cpu_model_expansion(CpuModelExpansionType 
>> type,
>>  QDict *props = NULL;
>>  

[PATCH v2 2/3] target/s390x: add support for "disable-deprecated-feats" expansion option

2024-04-23 Thread Collin Walling
Retain a list of deprecated features disjoint from any particular
CPU model. When a query-cpu-model-expansion is provided with the
"disable-deprecated-feats" option set, the resulting properties list
will include all deprecated features paired with false. Example:

{ ... "bpb": false, "csske": false, ...}

It is recommended that s390 guests operate with these features
explicitly disabled to ensure compatability with future hardware.

Signed-off-by: Collin Walling 
---
 target/s390x/cpu_features.c  | 14 ++
 target/s390x/cpu_features.h  |  1 +
 target/s390x/cpu_models_sysemu.c | 20 
 3 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index d28eb65845..efafc9711c 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap 
features, void *opaque,
 };
 }
 
+void s390_get_deprecated_features(S390FeatBitmap features)
+{
+static const int feats[] = {
+ /* CSSKE is deprecated on newer generations */
+ S390_FEAT_CONDITIONAL_SSKE,
+ S390_FEAT_BPB,
+};
+int i;
+
+for (i = 0; i < ARRAY_SIZE(feats); i++) {
+set_bit(feats[i], features);
+}
+}
+
 #define FEAT_GROUP_INIT(_name, _group, _desc)\
 {\
 .name = _name,   \
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index a9bd68a2e1..661a8cd6db 100644
--- a/target/s390x/cpu_features.h
+++ b/target/s390x/cpu_features.h
@@ -69,6 +69,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, 
S390FeatType type,
   uint8_t *data);
 void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque));
+void s390_get_deprecated_features(S390FeatBitmap features);
 
 /* Definition of a CPU feature group */
 typedef struct {
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index ef9fa80efd..b002819188 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -171,7 +171,8 @@ static void qdict_add_enabled_feat(const char *name, void 
*opaque)
 
 /* convert S390CPUDef into a static CpuModelInfo */
 static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
-bool delta_changes)
+bool delta_changes,
+bool disable_deprecated_feats)
 {
 QDict *qdict = qdict_new();
 S390FeatBitmap bitmap;
@@ -201,6 +202,13 @@ static void cpu_info_from_model(CpuModelInfo *info, const 
S390CPUModel *model,
 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
 }
 
+/* features flagged as deprecated */
+if (disable_deprecated_feats) {
+bitmap_zero(bitmap, S390_FEAT_MAX);
+s390_get_deprecated_features(bitmap);
+s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
+}
+
 if (!qdict_size(qdict)) {
 qobject_unref(qdict);
 } else {
@@ -219,11 +227,6 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 S390CPUModel s390_model;
 bool delta_changes = false;
 
-if (has_disable_deprecated_feats) {
-error_setg(, "Unsupported option 'disable-deprecated-feats'");
-return NULL;
-}
-
 /* convert it to our internal representation */
 cpu_model_from_info(_model, model, "model", );
 if (err) {
@@ -241,7 +244,8 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 /* convert it back to a static representation */
 expansion_info = g_new0(CpuModelExpansionInfo, 1);
 expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
-cpu_info_from_model(expansion_info->model, _model, delta_changes);
+cpu_info_from_model(expansion_info->model, _model,
+delta_changes, disable_deprecated_feats);
 return expansion_info;
 }
 
@@ -390,7 +394,7 @@ CpuModelBaselineInfo 
*qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
 
 baseline_info = g_new0(CpuModelBaselineInfo, 1);
 baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
-cpu_info_from_model(baseline_info->model, , true);
+cpu_info_from_model(baseline_info->model, , true, false);
 return baseline_info;
 }
 
-- 
2.43.0




[PATCH v2 3/3] target/s390x: flag te and cte as deprecated

2024-04-23 Thread Collin Walling
Add the CONSTRAINT_TRANSACTIONAL_EXE (cte) and TRANSACTIONAL_EXE (te)
to the list of deprecated features.

Signed-off-by: Collin Walling 
---
 target/s390x/cpu_features.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index efafc9711c..cb4e2b8920 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -218,6 +218,9 @@ void s390_get_deprecated_features(S390FeatBitmap features)
  /* CSSKE is deprecated on newer generations */
  S390_FEAT_CONDITIONAL_SSKE,
  S390_FEAT_BPB,
+ /* Deprecated on z16 */
+ S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+ S390_FEAT_TRANSACTIONAL_EXE
 };
 int i;
 
-- 
2.43.0




[PATCH v2 0/3] query-cpu-model-expansion: add disable-deprecated-feats arg

2024-04-23 Thread Collin Walling
The current implementation of query-cpu-model-expansion is lacking a way to
conditionally retrieve CPU models with properties (i.e. features) that are
flagged as deprecated set to disabled. To remedy this, a new optional boolean
"disable-deprecated-feats" argument has been added to the query.

Here is a sample QMP command that includes this new argument:

{ "execute": "query-cpu-model-expansion", "arguments": { "type": "full", 
"model": { "name": "host" }, "disable-deprecated-features": true}}

This patchset adds full support for this argument on s390x. A simple interface 
is
designed that contains an array of feature bits that are flagged for 
deprecation.
This list may be easily populated with more features in the future.

void s390_get_deprecated_features(S390FeatBitmap features)
{
static const int feats[] = {
 /* CSSKE is deprecated on newer generations */
 S390_FEAT_CONDITIONAL_SSKE,
 S390_FEAT_BPB,
 /* Deprecated on z16 */
 S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
 S390_FEAT_TRANSACTIONAL_EXE
};
int i;

for (i = 0; i < ARRAY_SIZE(feats); i++) {
set_bit(feats[i], features);
}
}

For architectures that support model expansion but do not support the new arg,
an error message will print to stdio if this option is present.

Use case example:

Newer s390 machines may signal the end-of-support for particular CPU features,
rendering guests operating with older CPU models incapable of running on
said machines. A manual effort to disable certain CPU features would be
required.

This feature may alleviate this issue by allowing for a query of a CPU model
with deprecated features listed in the props response paired with false. The
caller of this query may use this information to explicitly disable these
features for the guest's CPU model, ensuring a safe migration to the next
generation if desired.

I have developed a way for libvirt to make use of this functionality, but I
will hold back review on those patches until a QEMU interface is agreed upon.

Collin L. Walling (3):
  cpu-models: add "disable-deprecated-feats" option to cpu model
expansion
  target/s390x: add support for "disable-deprecated-feats" expansion
option
  target/s390x: flag te and cte as deprecated

 qapi/machine-target.json |  7 ++-
 target/arm/arm-qmp-cmds.c|  7 +++
 target/i386/cpu-sysemu.c |  7 +++
 target/s390x/cpu_features.c  | 17 +
 target/s390x/cpu_features.h  |  1 +
 target/s390x/cpu_models_sysemu.c | 17 ++---
 6 files changed, 52 insertions(+), 4 deletions(-)

-- 
2.43.0




[PATCH v2 1/3] cpu-models: add "disable-deprecated-feats" option to cpu model expansion

2024-04-23 Thread Collin Walling
This optional parameter for query-cpu-model-expansion enables CPU
model features flagged as deprecated to appear in the resulting
list of properties.

This commit does not add support beyond adding a new argument
to the query. All queries with this option present will result
in an error claiming this option is not supported.

Signed-off-by: Collin Walling 
---
 qapi/machine-target.json | 7 ++-
 target/arm/arm-qmp-cmds.c| 7 +++
 target/i386/cpu-sysemu.c | 7 +++
 target/s390x/cpu_models_sysemu.c | 7 +++
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 29e695aa06..b9da284d2d 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -285,6 +285,10 @@
 #
 # @type: expansion type, specifying how to expand the CPU model
 #
+# @disable-deprecated-feats: include CPU model features that are
+# flagged as deprecated. If supported, these features will appear
+# in the properties list paired with false.
+#
 # Returns: a CpuModelExpansionInfo describing the expanded CPU model
 #
 # Errors:
@@ -298,7 +302,8 @@
 ##
 { 'command': 'query-cpu-model-expansion',
   'data': { 'type': 'CpuModelExpansionType',
-'model': 'CpuModelInfo' },
+'model': 'CpuModelInfo',
+'*disable-deprecated-feats': 'bool' },
   'returns': 'CpuModelExpansionInfo',
   'if': { 'any': [ 'TARGET_S390X',
'TARGET_I386',
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 3cc8cc738b..1010d654e3 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -100,6 +100,8 @@ static const char *cpu_model_advertised_features[] = {
 
 CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType 
type,
  CpuModelInfo *model,
+ bool 
has_disable_deprecated_feats,
+ bool 
disable_deprecated_feats,
  Error **errp)
 {
 CpuModelExpansionInfo *expansion_info;
@@ -110,6 +112,11 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 const char *name;
 int i;
 
+if (has_disable_deprecated_feats) {
+error_setg(, "Unsupported option 'disable-deprecated-feats'");
+return NULL;
+}
+
 if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
 error_setg(errp, "The requested expansion type is not supported");
 return NULL;
diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
index 3f9093d285..c15786fb66 100644
--- a/target/i386/cpu-sysemu.c
+++ b/target/i386/cpu-sysemu.c
@@ -196,6 +196,8 @@ out:
 CpuModelExpansionInfo *
 qmp_query_cpu_model_expansion(CpuModelExpansionType type,
   CpuModelInfo *model,
+  bool 
has_disable_deprecated_feats,
+  bool 
disable_deprecated_feats,
   Error **errp)
 {
 X86CPU *xc = NULL;
@@ -204,6 +206,11 @@ qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 QDict *props = NULL;
 const char *base_name;
 
+if (has_disable_deprecated_feats) {
+error_setg(, "Unsupported option 'disable-deprecated-feats'");
+goto out;
+}
+
 xc = x86_cpu_from_model(model->name, model->props, "model.props", );
 if (err) {
 goto out;
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 2d99218069..ef9fa80efd 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -210,6 +210,8 @@ static void cpu_info_from_model(CpuModelInfo *info, const 
S390CPUModel *model,
 
 CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType 
type,
   CpuModelInfo *model,
+  bool 
has_disable_deprecated_feats,
+  bool 
disable_deprecated_feats,
   Error **errp)
 {
 Error *err = NULL;
@@ -217,6 +219,11 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 S390CPUModel s390_model;
 bool delta_changes = false;
 
+if (has_disable_deprecated_feats) {
+error_setg(, "Unsupported option 'disable-deprecated-feats'");
+return NULL;
+}
+
 /* convert it to our internal representation */
 cpu_model_from_info(_model, model, "model", );
 if (err) {
-- 
2.43.0




Re: [PATCH v1 1/2] target/s390x: introduce "host-recommended" option for model expansion

2023-09-14 Thread Collin Walling
On 9/12/23 02:57, David Hildenbrand wrote:
> On 11.09.23 22:52, Collin Walling wrote:
> 
> Patch subject is wrong (should contain "static-recommended")
> 
>> Newer S390 machines may drop support for features completely, rendering
>> guests operating with older CPU models incapable of running on said
>> machines. A manual effort to disable certain CPU features would be
>> required.
>>
>> To alleviate this issue, a list of "deprecated" features are now
>> retained within QEMU, and a new "static-recommended" CPU model expansion
>> type has been created to allow a query of the host-model with deprecated
>> features explicitly disabled.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>   qapi/machine-target.json |  8 +++-
>>   target/s390x/cpu_features.c  | 14 ++
>>   target/s390x/cpu_features.h  |  1 +
>>   target/s390x/cpu_models_sysemu.c | 26 +-
>>   4 files changed, 43 insertions(+), 6 deletions(-)
>>
>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>> index f0a6b72414..4dc891809d 100644
>> --- a/qapi/machine-target.json
>> +++ b/qapi/machine-target.json
>> @@ -42,6 +42,12 @@
>>   # to be migration-safe, but allows tooling to get an insight and
>>   # work with model details.
>>   #
>> +# @static-recommended: Expand to a static CPU model with property
>> +# changes suggested by the architecture. This is useful for
>> +# expanding a CPU model expected to operate in mixed
>> +# CPU-generation environments. The @static-recommended CPU
>> +# models are migration-safe.
>> +#
> 
> Can we instead make this a new parameter for query-cpu-model-expansion 
> ("no-deprecated-features" ? ), that properly gets rejected from other 
> archs when not supported?
> 
> [...]
> 

So instead of a "type": "static-recommended" add an entirely new
(optional) parameter key-value to the command?
"disable-deprecated-features": "true|false"?

>>   /* convert S390CPUDef into a static CpuModelInfo */
>>   static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel 
>> *model,
>> -bool delta_changes)
>> +bool delta_changes, bool disable_dep_feats)
> 
> "dep" can be misleading ("depended")
> 
> "no_deprecated_feat" ?
> 
> 

Good call. Tricky one to short-hand :)

With respect to labeling this as "no-deprecated-features", I think that
may also be misleading: it sounds like an exclusion, when in fact we
*want* the deprecated feats to show up paired with the false value. So I
think "disable-deprecated-features" is a better label. Would you agree?

-- 
Regards,
  Collin




[PATCH v1 2/2] target/s390x: flag te and cte as deprecated

2023-09-11 Thread Collin Walling
Add the CONSTRAINT_TRANSACTIONAL_EXE (cte) and TRANSACTIONAL_EXE (te)
under the list of deprecated features.

Signed-off-by: Collin Walling 
---
 target/s390x/cpu_features.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index efafc9711c..cb4e2b8920 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -218,6 +218,9 @@ void s390_get_deprecated_features(S390FeatBitmap features)
  /* CSSKE is deprecated on newer generations */
  S390_FEAT_CONDITIONAL_SSKE,
  S390_FEAT_BPB,
+ /* Deprecated on z16 */
+ S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+ S390_FEAT_TRANSACTIONAL_EXE
 };
 int i;
 
-- 
2.41.0




[PATCH v1 1/2] target/s390x: introduce "host-recommended" option for model expansion

2023-09-11 Thread Collin Walling
Newer S390 machines may drop support for features completely, rendering
guests operating with older CPU models incapable of running on said
machines. A manual effort to disable certain CPU features would be
required.

To alleviate this issue, a list of "deprecated" features are now
retained within QEMU, and a new "static-recommended" CPU model expansion
type has been created to allow a query of the host-model with deprecated
features explicitly disabled.

Signed-off-by: Collin Walling 
---
 qapi/machine-target.json |  8 +++-
 target/s390x/cpu_features.c  | 14 ++
 target/s390x/cpu_features.h  |  1 +
 target/s390x/cpu_models_sysemu.c | 26 +-
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f0a6b72414..4dc891809d 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -42,6 +42,12 @@
 # to be migration-safe, but allows tooling to get an insight and
 # work with model details.
 #
+# @static-recommended: Expand to a static CPU model with property
+# changes suggested by the architecture. This is useful for
+# expanding a CPU model expected to operate in mixed
+# CPU-generation environments. The @static-recommended CPU
+# models are migration-safe.
+#
 # Note: When a non-migration-safe CPU model is expanded in static
 # mode, some features enabled by the CPU model may be omitted,
 # because they can't be implemented by a static CPU model
@@ -55,7 +61,7 @@
 # Since: 2.8
 ##
 { 'enum': 'CpuModelExpansionType',
-  'data': [ 'static', 'full' ] }
+  'data': [ 'static', 'full', 'static-recommended' ] }
 
 ##
 # @CpuModelCompareResult:
diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index d28eb65845..efafc9711c 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -212,6 +212,20 @@ void s390_feat_bitmap_to_ascii(const S390FeatBitmap 
features, void *opaque,
 };
 }
 
+void s390_get_deprecated_features(S390FeatBitmap features)
+{
+static const int feats[] = {
+ /* CSSKE is deprecated on newer generations */
+ S390_FEAT_CONDITIONAL_SSKE,
+ S390_FEAT_BPB,
+};
+int i;
+
+for (i = 0; i < ARRAY_SIZE(feats); i++) {
+set_bit(feats[i], features);
+}
+}
+
 #define FEAT_GROUP_INIT(_name, _group, _desc)\
 {\
 .name = _name,   \
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index 87463f064d..5421762db5 100644
--- a/target/s390x/cpu_features.h
+++ b/target/s390x/cpu_features.h
@@ -68,6 +68,7 @@ void s390_add_from_feat_block(S390FeatBitmap features, 
S390FeatType type,
   uint8_t *data);
 void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
void (*fn)(const char *name, void *opaque));
+void s390_get_deprecated_features(S390FeatBitmap features);
 
 /* Definition of a CPU feature group */
 typedef struct {
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 63981bf36b..1aa3d076b4 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -176,7 +176,7 @@ static void qdict_add_enabled_feat(const char *name, void 
*opaque)
 
 /* convert S390CPUDef into a static CpuModelInfo */
 static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
-bool delta_changes)
+bool delta_changes, bool disable_dep_feats)
 {
 QDict *qdict = qdict_new();
 S390FeatBitmap bitmap;
@@ -198,6 +198,13 @@ static void cpu_info_from_model(CpuModelInfo *info, const 
S390CPUModel *model,
 if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
 s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
 }
+
+/* features flagged as deprecated */
+if (disable_dep_feats) {
+bitmap_zero(bitmap, S390_FEAT_MAX);
+s390_get_deprecated_features(bitmap);
+s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
+}
 } else {
 /* expand all features */
 s390_feat_bitmap_to_ascii(model->features, qdict,
@@ -221,6 +228,7 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 CpuModelExpansionInfo *expansion_info = NULL;
 S390CPUModel s390_model;
 bool delta_changes = false;
+bool disable_dep_feats = false;
 
 /* convert it to our internal representation */
 cpu_model_from_info(_model, model, );
@@ -229,9 +237,16 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 return NULL;
 }
 
-if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) {
+switch (type) {
+case CPU_MODEL_EXPANSION_TYPE_STATIC_RECOMMENDED:
+  

Re: [RFC PATCH] s390: kvm: reduce frequency of CPU syncs of diag318 info

2021-12-02 Thread Collin Walling
On 11/23/21 01:14, Christian Borntraeger wrote:
> 
> Am 22.11.21 um 23:33 schrieb Collin Walling:
>> DIAGNOSE 0318 is invoked only once during IPL. As such, the
>> diag318 info will only change once initially and during resets.
>> Let's only sync the register to convey the info to KVM if and
>> only if the diag318 info has changed. Only set the dirty bit
>> flag for diag318 whenever it must be updated.
> 
> Is this really necessary? In my logs the sync only happens for larger
> changes (like reset) operations and then yes we log again.
> But I think it is ok to see such a log entry in these rare events.

Albeit a micro-optimization, I don't see why the diag318 dirtied bit
must to be set during /every/ sync. It makes more sense to set the flag
after the register was actually modified.

>>
>> The migration handler will invoke the set_diag318 helper on
>> post_load to ensure the info is set on the destination machine.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>   target/s390x/kvm/kvm.c |  5 -
>>   target/s390x/machine.c | 14 ++
>>   2 files changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
>> index 6acf14d5ec..6a141399f7 100644
>> --- a/target/s390x/kvm/kvm.c
>> +++ b/target/s390x/kvm/kvm.c
>> @@ -599,11 +599,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
>>   cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ETOKEN;
>>   }
>>   -    if (can_sync_regs(cs, KVM_SYNC_DIAG318)) {
>> -    cs->kvm_run->s.regs.diag318 = env->diag318_info;
>> -    cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
>> -    }
>> -
>>   /* Finally the prefix */
>>   if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
>>   cs->kvm_run->s.regs.prefix = env->psa;
>> diff --git a/target/s390x/machine.c b/target/s390x/machine.c
>> index 37a076858c..a5d113ce3a 100644
>> --- a/target/s390x/machine.c
>> +++ b/target/s390x/machine.c
>> @@ -234,6 +234,19 @@ const VMStateDescription vmstate_etoken = {
>>   }
>>   };
>>   +static int diag318_post_load(void *opaque, int version_id)
>> +{
>> +    S390CPU *cpu = opaque;
>> +    CPUState *cs = CPU(cpu);
>> +    CPUS390XState *env = _CPU(cs)->env;
>> +
>> +    if (kvm_enabled()) {
>> +    kvm_s390_set_diag318(cs, env->diag318_info);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   static bool diag318_needed(void *opaque)
>>   {
>>   return s390_has_feat(S390_FEAT_DIAG_318);
>> @@ -243,6 +256,7 @@ const VMStateDescription vmstate_diag318 = {
>>   .name = "cpu/diag318",
>>   .version_id = 1,
>>   .minimum_version_id = 1,
>> +    .post_load = diag318_post_load,
>>   .needed = diag318_needed,
>>   .fields = (VMStateField[]) {
>>   VMSTATE_UINT64(env.diag318_info, S390CPU),
>>
> 


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4] s390: kvm: adjust diag318 resets to retain data

2021-12-02 Thread Collin Walling
On 12/2/21 04:23, Thomas Huth wrote:
> On 01/12/2021 19.45, Collin Walling wrote:
>> Polite ping. I may have missed if this patch was picked already. Thanks!
> 
> I've already queued it to my s390x-next branch:
> 
>  https://gitlab.com/thuth/qemu/-/commits/s390x-next/
> 
> It just came in very late for 6.2, and it didn't seem too critical to
> me, so I didn't sent a separate pull request for this one. Thus it will
> get merged once the hard freeze period of QEMU is over.
> 
>  Thomas
> 

Apologies, I missed this. My mail filters are sometimes messed up and I
didn't see this thread. All is good :)

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4] s390: kvm: adjust diag318 resets to retain data

2021-12-01 Thread Collin Walling
Polite ping. I may have missed if this patch was picked already. Thanks!


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [RFC PATCH] s390: kvm: reduce frequency of CPU syncs of diag318 info

2021-11-22 Thread Collin Walling
On 11/22/21 17:33, Collin Walling wrote:
> DIAGNOSE 0318 is invoked only once during IPL. As such, the
> diag318 info will only change once initially and during resets.
> Let's only sync the register to convey the info to KVM if and
> only if the diag318 info has changed. Only set the dirty bit
> flag for diag318 whenever it must be updated.
> 
> The migration handler will invoke the set_diag318 helper on
> post_load to ensure the info is set on the destination machine.
> 
> Signed-off-by: Collin Walling 

This is a long-overdue response to this thread:
https://www.spinics.net/lists/kvm/msg258071.html

> ---
>  target/s390x/kvm/kvm.c |  5 -
>  target/s390x/machine.c | 14 ++
>  2 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
> index 6acf14d5ec..6a141399f7 100644
> --- a/target/s390x/kvm/kvm.c
> +++ b/target/s390x/kvm/kvm.c
> @@ -599,11 +599,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
>  cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ETOKEN;
>  }
>  
> -if (can_sync_regs(cs, KVM_SYNC_DIAG318)) {
> -cs->kvm_run->s.regs.diag318 = env->diag318_info;
> -cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
> -}
> -
>  /* Finally the prefix */
>  if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
>  cs->kvm_run->s.regs.prefix = env->psa;
> diff --git a/target/s390x/machine.c b/target/s390x/machine.c
> index 37a076858c..a5d113ce3a 100644
> --- a/target/s390x/machine.c
> +++ b/target/s390x/machine.c
> @@ -234,6 +234,19 @@ const VMStateDescription vmstate_etoken = {
>  }
>  };
>  
> +static int diag318_post_load(void *opaque, int version_id)
> +{
> +S390CPU *cpu = opaque;
> +CPUState *cs = CPU(cpu);
> +CPUS390XState *env = _CPU(cs)->env;
> +
> +if (kvm_enabled()) {
> +kvm_s390_set_diag318(cs, env->diag318_info);
> +}
> +
> +return 0;
> +}
> +
>  static bool diag318_needed(void *opaque)
>  {
>  return s390_has_feat(S390_FEAT_DIAG_318);
> @@ -243,6 +256,7 @@ const VMStateDescription vmstate_diag318 = {
>  .name = "cpu/diag318",
>  .version_id = 1,
>  .minimum_version_id = 1,
> +.post_load = diag318_post_load,
>  .needed = diag318_needed,
>  .fields = (VMStateField[]) {
>  VMSTATE_UINT64(env.diag318_info, S390CPU),
> 


-- 
Regards,
Collin

Stay safe and stay healthy



[RFC PATCH] s390: kvm: reduce frequency of CPU syncs of diag318 info

2021-11-22 Thread Collin Walling
DIAGNOSE 0318 is invoked only once during IPL. As such, the
diag318 info will only change once initially and during resets.
Let's only sync the register to convey the info to KVM if and
only if the diag318 info has changed. Only set the dirty bit
flag for diag318 whenever it must be updated.

The migration handler will invoke the set_diag318 helper on
post_load to ensure the info is set on the destination machine.

Signed-off-by: Collin Walling 
---
 target/s390x/kvm/kvm.c |  5 -
 target/s390x/machine.c | 14 ++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 6acf14d5ec..6a141399f7 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -599,11 +599,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ETOKEN;
 }
 
-if (can_sync_regs(cs, KVM_SYNC_DIAG318)) {
-cs->kvm_run->s.regs.diag318 = env->diag318_info;
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
-}
-
 /* Finally the prefix */
 if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
 cs->kvm_run->s.regs.prefix = env->psa;
diff --git a/target/s390x/machine.c b/target/s390x/machine.c
index 37a076858c..a5d113ce3a 100644
--- a/target/s390x/machine.c
+++ b/target/s390x/machine.c
@@ -234,6 +234,19 @@ const VMStateDescription vmstate_etoken = {
 }
 };
 
+static int diag318_post_load(void *opaque, int version_id)
+{
+S390CPU *cpu = opaque;
+CPUState *cs = CPU(cpu);
+CPUS390XState *env = _CPU(cs)->env;
+
+if (kvm_enabled()) {
+kvm_s390_set_diag318(cs, env->diag318_info);
+}
+
+return 0;
+}
+
 static bool diag318_needed(void *opaque)
 {
 return s390_has_feat(S390_FEAT_DIAG_318);
@@ -243,6 +256,7 @@ const VMStateDescription vmstate_diag318 = {
 .name = "cpu/diag318",
 .version_id = 1,
 .minimum_version_id = 1,
+.post_load = diag318_post_load,
 .needed = diag318_needed,
 .fields = (VMStateField[]) {
 VMSTATE_UINT64(env.diag318_info, S390CPU),
-- 
2.31.1




Re: [PATCH v3] s390: kvm: adjust diag318 resets to retain data

2021-11-17 Thread Collin Walling
On 11/17/21 02:43, Christian Borntraeger wrote:
> Am 09.11.21 um 21:56 schrieb Collin Walling:
>> The CPNC portion of the diag 318 data is erroneously reset during an
>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>> diag318_info field within the CPUS390XState struct such that it is
>> only zeroed during a clear reset. This way, the CPNC will be retained
>> for each VCPU in the configuration after the diag 318 instruction
>> has been invoked.
>>
>> Signed-off-by: Collin Walling 
>> Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
>> Reported-by: Christian Borntraeger 
> 
> Reviewed-by: Christian Borntraeger 
> 
> maybe add cc stable just in case there will be one.
> Can you resend with the final patch description and add Thomas as TO
> (not cc)
> as this should probably go via Thomas tree.

Done. Thank you.

>> ---
>>
>> Changelog:
>>
>>  v2
>>  - handler uses run_on_cpu again
>>  - reworded commit message slightly
>>  - added fixes and reported-by tags
>>
>>  v3
>>  - nixed code reduction changes
>>  - added a comment to diag318 handler to briefly describe
>>  when relevent data is zeroed
>>
>> ---
>>   target/s390x/cpu.h | 4 ++--
>>   target/s390x/kvm/kvm.c | 4 
>>   2 files changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>> index 3153d053e9..88aace36ff 100644
>> --- a/target/s390x/cpu.h
>> +++ b/target/s390x/cpu.h
>> @@ -63,6 +63,8 @@ struct CPUS390XState {
>>   uint64_t etoken;   /* etoken */
>>   uint64_t etoken_extension; /* etoken extension */
>>   +    uint64_t diag318_info;
>> +
>>   /* Fields up to this point are not cleared by initial CPU reset */
>>   struct {} start_initial_reset_fields;
>>   @@ -118,8 +120,6 @@ struct CPUS390XState {
>>   uint16_t external_call_addr;
>>   DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
>>   -    uint64_t diag318_info;
>> -
>>   #if !defined(CONFIG_USER_ONLY)
>>   uint64_t tlb_fill_tec;   /* translation exception code during
>> tlb_fill */
>>   int tlb_fill_exc;    /* exception number seen during
>> tlb_fill */
>> diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
>> index 5b1fdb55c4..6acf14d5ec 100644
>> --- a/target/s390x/kvm/kvm.c
>> +++ b/target/s390x/kvm/kvm.c
>> @@ -1585,6 +1585,10 @@ void kvm_s390_set_diag318(CPUState *cs,
>> uint64_t diag318_info)
>>   env->diag318_info = diag318_info;
>>   cs->kvm_run->s.regs.diag318 = diag318_info;
>>   cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
>> +    /*
>> + * diag 318 info is zeroed during a clear reset and
>> + * diag 308 IPL subcodes.
>> + */
>>   }
>>   }
>>  
> 


-- 
Regards,
Collin

Stay safe and stay healthy



[PATCH v4] s390: kvm: adjust diag318 resets to retain data

2021-11-17 Thread Collin Walling
The CPNC portion of the diag318 data is erroneously reset during an
initial CPU reset caused by SIGP. Let's go ahead and relocate the
diag318_info field within the CPUS390XState struct such that it is
only zeroed during a clear reset. This way, the CPNC will be retained
for each VCPU in the configuration after the diag318 instruction
has been invoked.

The s390_machine_reset code already takes care of zeroing the diag318
data on VM resets, which also cover resets caused by diag308.

Signed-off-by: Collin Walling 
Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
Reported-by: Christian Borntraeger 
Reviewed-by: Janosch Frank 
Reviewed-by: Christian Borntraeger  
---

Changelog:

v4
- fixed up commit message and added r-b's

v3
- reverted changes from previous versions
- simply relocate diag318_info in CPU State struct
- add comment in set_diag318 to explain resets

v2
- handler uses run_on_cpu again
- reworded commit message slightly
- added fixes and reported-by tags 

v3
- nixed code reduction changes
- added a comment to diag318 handler to briefly describe
when relevent data is zeroed

---
 target/s390x/cpu.h | 4 ++--
 target/s390x/kvm/kvm.c | 4 
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 3153d053e9..88aace36ff 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -63,6 +63,8 @@ struct CPUS390XState {
 uint64_t etoken;   /* etoken */
 uint64_t etoken_extension; /* etoken extension */
 
+uint64_t diag318_info;
+
 /* Fields up to this point are not cleared by initial CPU reset */
 struct {} start_initial_reset_fields;
 
@@ -118,8 +120,6 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
-uint64_t diag318_info;
-
 #if !defined(CONFIG_USER_ONLY)
 uint64_t tlb_fill_tec;   /* translation exception code during tlb_fill */
 int tlb_fill_exc;/* exception number seen during tlb_fill */
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 5b1fdb55c4..6acf14d5ec 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -1585,6 +1585,10 @@ void kvm_s390_set_diag318(CPUState *cs, uint64_t 
diag318_info)
 env->diag318_info = diag318_info;
 cs->kvm_run->s.regs.diag318 = diag318_info;
 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
+/*
+ * diag 318 info is zeroed during a clear reset and
+ * diag 308 IPL subcodes.
+ */
 }
 }
 
-- 
2.31.1




Re: [PATCH v3] s390: kvm: adjust diag318 resets to retain data

2021-11-10 Thread Collin Walling
On 11/10/21 07:42, Janosch Frank wrote:
> On 11/9/21 21:56, Collin Walling wrote:
>> The CPNC portion of the diag 318 data is erroneously reset during an
>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>> diag318_info field within the CPUS390XState struct such that it is
>> only zeroed during a clear reset. This way, the CPNC will be retained
>> for each VCPU in the configuration after the diag 318 instruction
>> has been invoked.
> 
> I'd add something like:
> The s390 machine reset code takes care of zeroing the diag318 data on VM
> resets which also cover resets caused by diag308.
> 
>>
>> Signed-off-by: Collin Walling 
>> Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
>> Reported-by: Christian Borntraeger 
>> ---
> 
> Reviewed-by: Janosch Frank 

The CPNC portion of the diag318 data is erroneously reset during an
initial CPU reset caused by SIGP. Let's go ahead and relocate the
diag318_info field within the CPUS390XState struct such that it is
only zeroed during a clear reset. This way, the CPNC will be retained
for each VCPU in the configuration after the diag318 instruction
has been invoked.

The s390_machine_reset code already takes care of zeroing the diag318
data on VM resets, which also cover resets caused by diag308.

Signed-off-by: Collin Walling 
Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
Reported-by: Christian Borntraeger 
Reviewed-by: Janosch Frank 

> 
>>
>> Changelog:
>>
>>  v2
>>  - handler uses run_on_cpu again
>>  - reworded commit message slightly
>>  - added fixes and reported-by tags
>>
>>  v3
>>  - nixed code reduction changes
>>  - added a comment to diag318 handler to briefly describe
>>  when relevent data is zeroed
>>
>> ---
>>   target/s390x/cpu.h | 4 ++--
>>   target/s390x/kvm/kvm.c | 4 
>>   2 files changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>> index 3153d053e9..88aace36ff 100644
>> --- a/target/s390x/cpu.h
>> +++ b/target/s390x/cpu.h
>> @@ -63,6 +63,8 @@ struct CPUS390XState {
>>   uint64_t etoken;   /* etoken */
>>   uint64_t etoken_extension; /* etoken extension */
>>   +    uint64_t diag318_info;
>> +
>>   /* Fields up to this point are not cleared by initial CPU reset */
>>   struct {} start_initial_reset_fields;
>>   @@ -118,8 +120,6 @@ struct CPUS390XState {
>>   uint16_t external_call_addr;
>>   DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
>>   -    uint64_t diag318_info;
>> -
>>   #if !defined(CONFIG_USER_ONLY)
>>   uint64_t tlb_fill_tec;   /* translation exception code during
>> tlb_fill */
>>   int tlb_fill_exc;    /* exception number seen during
>> tlb_fill */
>> diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
>> index 5b1fdb55c4..6acf14d5ec 100644
>> --- a/target/s390x/kvm/kvm.c
>> +++ b/target/s390x/kvm/kvm.c
>> @@ -1585,6 +1585,10 @@ void kvm_s390_set_diag318(CPUState *cs,
>> uint64_t diag318_info)
>>   env->diag318_info = diag318_info;
>>   cs->kvm_run->s.regs.diag318 = diag318_info;
>>   cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
>> +    /*
>> + * diag 318 info is zeroed during a clear reset and
>> + * diag 308 IPL subcodes.
>> + */
>>   }
>>   }
>>  
> 
> 


-- 
Regards,
Collin

Stay safe and stay healthy



[PATCH v3] s390: kvm: adjust diag318 resets to retain data

2021-11-09 Thread Collin Walling
The CPNC portion of the diag 318 data is erroneously reset during an
initial CPU reset caused by SIGP. Let's go ahead and relocate the
diag318_info field within the CPUS390XState struct such that it is
only zeroed during a clear reset. This way, the CPNC will be retained
for each VCPU in the configuration after the diag 318 instruction
has been invoked.

Signed-off-by: Collin Walling 
Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
Reported-by: Christian Borntraeger 
---

Changelog:

v2
- handler uses run_on_cpu again
- reworded commit message slightly
- added fixes and reported-by tags 

v3
- nixed code reduction changes
- added a comment to diag318 handler to briefly describe
when relevent data is zeroed

---
 target/s390x/cpu.h | 4 ++--
 target/s390x/kvm/kvm.c | 4 
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 3153d053e9..88aace36ff 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -63,6 +63,8 @@ struct CPUS390XState {
 uint64_t etoken;   /* etoken */
 uint64_t etoken_extension; /* etoken extension */
 
+uint64_t diag318_info;
+
 /* Fields up to this point are not cleared by initial CPU reset */
 struct {} start_initial_reset_fields;
 
@@ -118,8 +120,6 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
-uint64_t diag318_info;
-
 #if !defined(CONFIG_USER_ONLY)
 uint64_t tlb_fill_tec;   /* translation exception code during tlb_fill */
 int tlb_fill_exc;/* exception number seen during tlb_fill */
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 5b1fdb55c4..6acf14d5ec 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -1585,6 +1585,10 @@ void kvm_s390_set_diag318(CPUState *cs, uint64_t 
diag318_info)
 env->diag318_info = diag318_info;
 cs->kvm_run->s.regs.diag318 = diag318_info;
 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
+/*
+ * diag 318 info is zeroed during a clear reset and
+ * diag 308 IPL subcodes.
+ */
 }
 }
 
-- 
2.31.1




Re: [PATCH v2] s390x: kvm: adjust diag318 resets to retain data

2021-11-09 Thread Collin Walling
On 11/9/21 12:01, Janosch Frank wrote:
> On 11/9/21 16:58, Collin Walling wrote:
>> On 11/9/21 05:48, Janosch Frank wrote:
>>> On 11/9/21 08:32, Christian Borntraeger wrote:
>>>>
>>>>
>>>> Am 08.11.21 um 22:13 schrieb Collin Walling:
>>>>> The CPNC portion of the diag 318 data is erroneously reset during an
>>>>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>>>>> diag318_info field within the CPUS390XState struct such that it is
>>>>> only zeroed during a clear reset. This way, the CPNC will be retained
>>>>> for each VCPU in the configuration after the diag 318 instruction
>>>>> has been invoked.
>>>>>
>>>>> Additionally, the diag 318 data reset is handled via the CPU reset
>>>>> code during a clear reset. This means some of the diag 318-specific
>>>>> reset code can now be removed.
>>>>>
>>>>> Signed-off-by: Collin Walling 
>>>>> Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
>>>>> Reported-by: Christian Borntraeger 
>>>>
>>>> It would be good to add at least a comment in the diag308 handlers
>>>> where the value of cpnc is resetted during the resets that Janosch
>>>> mentioned.
>>>>>
>>>>> ---
>>>>>
>>>>> Changelog:
>>>>>
>>>>>  v2
>>>>>  - handler uses run_on_cpu again
>>>>>  - reworded commit message slightly
>>>>>  - added fixes and reported-by tags
>>>>>
>>>>> ---
>>>>>     hw/s390x/s390-virtio-ccw.c   |  3 ---
>>>>>     target/s390x/cpu-sysemu.c    |  7 ---
>>>>>     target/s390x/cpu.h   |  5 ++---
>>>>>     target/s390x/kvm/kvm.c   | 14 +-
>>>>>     target/s390x/kvm/kvm_s390x.h |  1 -
>>>>>     5 files changed, 7 insertions(+), 23 deletions(-)
>>>>>
>>>>> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
>>>>> index 653587ea62..51dcb83b0c 100644
>>>>> --- a/hw/s390x/s390-virtio-ccw.c
>>>>> +++ b/hw/s390x/s390-virtio-ccw.c
>>>>> @@ -489,9 +489,6 @@ static void s390_machine_reset(MachineState
>>>>> *machine)
>>>>>     g_assert_not_reached();
>>>>>     }
>>>>>     -    CPU_FOREACH(t) {
>>>>> -    run_on_cpu(t, s390_do_cpu_set_diag318,
>>>>> RUN_ON_CPU_HOST_ULONG(0));
>>>>> -    }
>>>
>>> This needs to stay for the move to the clear reset area to work on other
>>> diag308 subcodes. The reset will then be done twice for the clear reset
>>> but that's fine.
>>>
>>> Moving the diag318 data into the clear area means we only reset it on a
>>> full cpu reset which is only done for diagnose 308 subcode 0 and maybe a
>>> QEMU reset, I didn't fully follow the code there.
>>>
>>> The other subcodes do an initial reset on the calling cpu and normal
>>> resets on the others or just normal resets which don't touch the 318
>>> data if we move it into the clear reset area.
>>>> Or did I miss something fundamental here?
>>>
>>>
>> While the diag318 data will not be cleared during an initial and load
>> normal resets _directly_, the s390_machine_reset function ends with the
>> call below:
>>
>>>>>     s390_ipl_clear_reset_request();
>>>>>     }
>>
>> The clear reset request is invoked after each of the reset types at the
>> tail end of the function. Because of this, the diag318 data will be
>> reset during the 308 subcodes by way of the clear reset at the end.
> 
> This changes a few values in ipl.c and is not in fact a cpu clear reset.
> 
> QEMU knows a lot of resets. The VM resets here mainly depict diagnose
> 308 subcodes which set the cpus and the channel subsystem into a
> specific state for the purpose of IPL (subcode 3 and 4 are how we IPL,
> subcode 10 is PV IPL).
> 
> The CPU resets can be triggered by SIGP (normal and initial, NOT clear
> reset) or are triggered as part of a VM reset mentioned above.
> 

Makes sense to me now. I had the terminology between our s390-specific
stuff and the QEMU code jumbled, but it's clear to me what's actually
happening here. Thank you for the explanation.

I'll send the next version which simply relocates the diag318_info in
the CPU state struct. The re

Re: [PATCH v2] s390x: kvm: adjust diag318 resets to retain data

2021-11-09 Thread Collin Walling
On 11/9/21 05:48, Janosch Frank wrote:
> On 11/9/21 08:32, Christian Borntraeger wrote:
>>
>>
>> Am 08.11.21 um 22:13 schrieb Collin Walling:
>>> The CPNC portion of the diag 318 data is erroneously reset during an
>>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>>> diag318_info field within the CPUS390XState struct such that it is
>>> only zeroed during a clear reset. This way, the CPNC will be retained
>>> for each VCPU in the configuration after the diag 318 instruction
>>> has been invoked.
>>>
>>> Additionally, the diag 318 data reset is handled via the CPU reset
>>> code during a clear reset. This means some of the diag 318-specific
>>> reset code can now be removed.
>>>
>>> Signed-off-by: Collin Walling 
>>> Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
>>> Reported-by: Christian Borntraeger 
>>
>> It would be good to add at least a comment in the diag308 handlers
>> where the value of cpnc is resetted during the resets that Janosch
>> mentioned.
>>>
>>> ---
>>>
>>> Changelog:
>>>
>>> v2
>>> - handler uses run_on_cpu again
>>> - reworded commit message slightly
>>> - added fixes and reported-by tags
>>>
>>> ---
>>>    hw/s390x/s390-virtio-ccw.c   |  3 ---
>>>    target/s390x/cpu-sysemu.c    |  7 ---
>>>    target/s390x/cpu.h   |  5 ++---
>>>    target/s390x/kvm/kvm.c   | 14 +-
>>>    target/s390x/kvm/kvm_s390x.h |  1 -
>>>    5 files changed, 7 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
>>> index 653587ea62..51dcb83b0c 100644
>>> --- a/hw/s390x/s390-virtio-ccw.c
>>> +++ b/hw/s390x/s390-virtio-ccw.c
>>> @@ -489,9 +489,6 @@ static void s390_machine_reset(MachineState
>>> *machine)
>>>    g_assert_not_reached();
>>>    }
>>>    -    CPU_FOREACH(t) {
>>> -    run_on_cpu(t, s390_do_cpu_set_diag318,
>>> RUN_ON_CPU_HOST_ULONG(0));
>>> -    }
> 
> This needs to stay for the move to the clear reset area to work on other
> diag308 subcodes. The reset will then be done twice for the clear reset
> but that's fine.
> 
> Moving the diag318 data into the clear area means we only reset it on a
> full cpu reset which is only done for diagnose 308 subcode 0 and maybe a
> QEMU reset, I didn't fully follow the code there.
> 
> The other subcodes do an initial reset on the calling cpu and normal
> resets on the others or just normal resets which don't touch the 318
> data if we move it into the clear reset area.
>> Or did I miss something fundamental here?
> 
>
While the diag318 data will not be cleared during an initial and load
normal resets _directly_, the s390_machine_reset function ends with the
call below:

>>>    s390_ipl_clear_reset_request();
>>>    }

The clear reset request is invoked after each of the reset types at the
tail end of the function. Because of this, the diag318 data will be
reset during the 308 subcodes by way of the clear reset at the end.

>>>    diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
>>> index 5471e01ee8..6d9f6d4402 100644
>>> --- a/target/s390x/cpu-sysemu.c
>>> +++ b/target/s390x/cpu-sysemu.c
>>> @@ -299,10 +299,3 @@ void s390_enable_css_support(S390CPU *cpu)
>>>    kvm_s390_enable_css_support(cpu);
>>>    }
>>>    }
>>> -
>>> -void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
>>> -{
>>> -    if (kvm_enabled()) {
>>> -    kvm_s390_set_diag318(cs, arg.host_ulong);
>>> -    }
>>> -}
>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>> index 3153d053e9..1b94b91d87 100644
>>> --- a/target/s390x/cpu.h
>>> +++ b/target/s390x/cpu.h
>>> @@ -63,6 +63,8 @@ struct CPUS390XState {
>>>    uint64_t etoken;   /* etoken */
>>>    uint64_t etoken_extension; /* etoken extension */
>>>    +    uint64_t diag318_info;
>>> +
>>>    /* Fields up to this point are not cleared by initial CPU
>>> reset */
>>>    struct {} start_initial_reset_fields;
>>>    @@ -118,8 +120,6 @@ struct CPUS390XState {
>>>    uint16_t external_call_addr;
>>>    DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
>>>    -    uint64_t diag318_info;
>>> -
>>>    #if !defined(CONFIG_USER

[PATCH v2] s390x: kvm: adjust diag318 resets to retain data

2021-11-08 Thread Collin Walling
The CPNC portion of the diag 318 data is erroneously reset during an
initial CPU reset caused by SIGP. Let's go ahead and relocate the
diag318_info field within the CPUS390XState struct such that it is
only zeroed during a clear reset. This way, the CPNC will be retained
for each VCPU in the configuration after the diag 318 instruction
has been invoked.

Additionally, the diag 318 data reset is handled via the CPU reset
code during a clear reset. This means some of the diag 318-specific
reset code can now be removed.

Signed-off-by: Collin Walling 
Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
Reported-by: Christian Borntraeger 

---

Changelog:

v2
- handler uses run_on_cpu again
- reworded commit message slightly
- added fixes and reported-by tags

---
 hw/s390x/s390-virtio-ccw.c   |  3 ---
 target/s390x/cpu-sysemu.c|  7 ---
 target/s390x/cpu.h   |  5 ++---
 target/s390x/kvm/kvm.c   | 14 +-
 target/s390x/kvm/kvm_s390x.h |  1 -
 5 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 653587ea62..51dcb83b0c 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -489,9 +489,6 @@ static void s390_machine_reset(MachineState *machine)
 g_assert_not_reached();
 }
 
-CPU_FOREACH(t) {
-run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
-}
 s390_ipl_clear_reset_request();
 }
 
diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
index 5471e01ee8..6d9f6d4402 100644
--- a/target/s390x/cpu-sysemu.c
+++ b/target/s390x/cpu-sysemu.c
@@ -299,10 +299,3 @@ void s390_enable_css_support(S390CPU *cpu)
 kvm_s390_enable_css_support(cpu);
 }
 }
-
-void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
-{
-if (kvm_enabled()) {
-kvm_s390_set_diag318(cs, arg.host_ulong);
-}
-}
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 3153d053e9..1b94b91d87 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -63,6 +63,8 @@ struct CPUS390XState {
 uint64_t etoken;   /* etoken */
 uint64_t etoken_extension; /* etoken extension */
 
+uint64_t diag318_info;
+
 /* Fields up to this point are not cleared by initial CPU reset */
 struct {} start_initial_reset_fields;
 
@@ -118,8 +120,6 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
-uint64_t diag318_info;
-
 #if !defined(CONFIG_USER_ONLY)
 uint64_t tlb_fill_tec;   /* translation exception code during tlb_fill */
 int tlb_fill_exc;/* exception number seen during tlb_fill */
@@ -780,7 +780,6 @@ int s390_set_memory_limit(uint64_t new_limit, uint64_t 
*hw_limit);
 void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
 void s390_cmma_reset(void);
 void s390_enable_css_support(S390CPU *cpu);
-void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
 int vq, bool assign);
 #ifndef CONFIG_USER_ONLY
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 5b1fdb55c4..8970d9ca55 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -1576,16 +1576,13 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct 
kvm_run *run)
 return -ENOENT;
 }
 
-void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
+static void set_diag_318(CPUState *cs, run_on_cpu_data arg)
 {
 CPUS390XState *env = _CPU(cs)->env;
 
-/* Feat bit is set only if KVM supports sync for diag318 */
-if (s390_has_feat(S390_FEAT_DIAG_318)) {
-env->diag318_info = diag318_info;
-cs->kvm_run->s.regs.diag318 = diag318_info;
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
-}
+env->diag318_info = arg.host_ulong;
+cs->kvm_run->s.regs.diag318 = arg.host_ulong;
+cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
 }
 
 static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
@@ -1604,8 +1601,7 @@ static void handle_diag_318(S390CPU *cpu, struct kvm_run 
*run)
 }
 
 CPU_FOREACH(t) {
-run_on_cpu(t, s390_do_cpu_set_diag318,
-   RUN_ON_CPU_HOST_ULONG(diag318_info));
+run_on_cpu(t, set_diag_318, RUN_ON_CPU_HOST_ULONG(diag318_info));
 }
 }
 
diff --git a/target/s390x/kvm/kvm_s390x.h b/target/s390x/kvm/kvm_s390x.h
index 05a5e1e6f4..8c244ee84d 100644
--- a/target/s390x/kvm/kvm_s390x.h
+++ b/target/s390x/kvm/kvm_s390x.h
@@ -44,6 +44,5 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error 
**errp);
 void kvm_s390_crypto_reset(void);
 void kvm_s390_restart_interrupt(S390CPU *cpu);
 void kvm_s390_stop_interrupt(S390CPU *cpu);
-void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info);
 
 #endif /* KVM_S390X_H */
-- 
2.31.1




Re: [PATCH] s390x: kvm: adjust diag318 resets to retain data

2021-11-08 Thread Collin Walling
On 11/8/21 12:40, Christian Borntraeger wrote:
> 
> 
> Am 08.11.21 um 18:02 schrieb Janosch Frank:
>> On 11/5/21 23:46, Collin Walling wrote:
>>> The CPNC portion of the diag 318 data is erroneously reset during an
>>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>>> diag318_info field within the CPUS390XState struct such that it is
>>> only zeroed during a clear reset. This way, the CPNC will be retained
>>> for each VCPU in the configuration after the diag 318 instruction
>>> has been invoked by the kernel.
>>>
>>> Additionally, the diag 318 data reset is handled via the CPU reset
>>> code. The set_diag318 code can be merged into the handler function
>>> and the helper functions can consequently be removed.
>>>
>>> Signed-off-by: Collin Walling 
>>
>> Fixes tag?
>>
>>> ---
>>>   hw/s390x/s390-virtio-ccw.c   |  3 ---
>>>   target/s390x/cpu-sysemu.c    |  7 ---
>>>   target/s390x/cpu.h   |  5 ++---
>>>   target/s390x/kvm/kvm.c   | 19 +--
>>>   target/s390x/kvm/kvm_s390x.h |  1 -
>>>   5 files changed, 7 insertions(+), 28 deletions(-)
>>>
>>> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
>>> index 653587ea62..51dcb83b0c 100644
>>> --- a/hw/s390x/s390-virtio-ccw.c
>>> +++ b/hw/s390x/s390-virtio-ccw.c
>>> @@ -489,9 +489,6 @@ static void s390_machine_reset(MachineState
>>> *machine)
>>>   g_assert_not_reached();
>>>   }
>>> -    CPU_FOREACH(t) {
>>> -    run_on_cpu(t, s390_do_cpu_set_diag318,
>>> RUN_ON_CPU_HOST_ULONG(0));
>>> -    }
>>>   s390_ipl_clear_reset_request();
>>>   }
>>> diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
>>> index 5471e01ee8..6d9f6d4402 100644
>>> --- a/target/s390x/cpu-sysemu.c
>>> +++ b/target/s390x/cpu-sysemu.c
>>> @@ -299,10 +299,3 @@ void s390_enable_css_support(S390CPU *cpu)
>>>   kvm_s390_enable_css_support(cpu);
>>>   }
>>>   }
>>> -
>>> -void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
>>> -{
>>> -    if (kvm_enabled()) {
>>> -    kvm_s390_set_diag318(cs, arg.host_ulong);
>>> -    }
>>> -}
>>> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
>>> index 3153d053e9..1b94b91d87 100644
>>> --- a/target/s390x/cpu.h
>>> +++ b/target/s390x/cpu.h
>>> @@ -63,6 +63,8 @@ struct CPUS390XState {
>>>   uint64_t etoken;   /* etoken */
>>>   uint64_t etoken_extension; /* etoken extension */
>>> +    uint64_t diag318_info;
>>
>> Before we brought this upstream I had a conversation with the
>> architect because I was confused about this myself. He said: SIGP does
>> not affect 318 data but all 308 subcode resets do (0,1,3,4).
>>
>> Hence I'd much rather move this out of the automatic reset areas and
>> clear it by hand for diag308 resets. And then add a big comment with a
>> warning to never move this into the automatic clearing areas.
> 
> the automatic cleaning areas are also used for the big hammer
> system_reset in QEMU which acts like a power cycle. And those fields are
> initialized always on such events.
>  So you cannot avoid clearing this for the big hammer things anyway.

The data needs to be reset during a clear reset as well. Correct me if
I'm wrong here: the 308 resets will invoke the qemu reset, which will
eventually invoke the machine reset. The s390_machine_reset code ends
with a clear reset request. I believe having the 318 field in the struct
accomplishes what we need: it is reset on clear and 308 subcodes and
avoids being tampered by SIGP.

>>
>>> +
>>>   /* Fields up to this point are not cleared by initial CPU reset */
>>>   struct {} start_initial_reset_fields;
>>> @@ -118,8 +120,6 @@ struct CPUS390XState {
>>>   uint16_t external_call_addr;
>>>   DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
>>> -    uint64_t diag318_info;
>>> -
>>>   #if !defined(CONFIG_USER_ONLY)
>>>   uint64_t tlb_fill_tec;   /* translation exception code during
>>> tlb_fill */
>>>   int tlb_fill_exc;    /* exception number seen during
>>> tlb_fill */
>>> @@ -780,7 +780,6 @@ int s390_set_memory_limit(uint64_t new_limit,
>>> uint64_t *hw_limit);
>>>   void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
>>>   void s390_cmma_reset(void);
>>&

Re: [PATCH] s390x: kvm: adjust diag318 resets to retain data

2021-11-08 Thread Collin Walling
On 11/8/21 12:02, Janosch Frank wrote:
> On 11/5/21 23:46, Collin Walling wrote:
>> The CPNC portion of the diag 318 data is erroneously reset during an
>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>> diag318_info field within the CPUS390XState struct such that it is
>> only zeroed during a clear reset. This way, the CPNC will be retained
>> for each VCPU in the configuration after the diag 318 instruction
>> has been invoked by the kernel.
>>
>> Additionally, the diag 318 data reset is handled via the CPU reset
>> code. The set_diag318 code can be merged into the handler function
>> and the helper functions can consequently be removed.
>>
>> Signed-off-by: Collin Walling 
> 
> Fixes tag?
> 

Will include this on v2 post. Thank you.

[...]

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH] s390x: kvm: adjust diag318 resets to retain data

2021-11-08 Thread Collin Walling
On 11/8/21 03:07, Christian Borntraeger wrote:
> 
> 
> Am 05.11.21 um 23:46 schrieb Collin Walling:
>> The CPNC portion of the diag 318 data is erroneously reset during an
>> initial CPU reset caused by SIGP. Let's go ahead and relocate the
>> diag318_info field within the CPUS390XState struct such that it is
>> only zeroed during a clear reset. This way, the CPNC will be retained
>> for each VCPU in the configuration after the diag 318 instruction
>> has been invoked by the kernel.
>>
>> Additionally, the diag 318 data reset is handled via the CPU reset
>> code. The set_diag318 code can be merged into the handler function
>> and the helper functions can consequently be removed.
>>
>> Signed-off-by: Collin Walling 

[...]

>> diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
>> index 5b1fdb55c4..ed9c477b6f 100644
>> --- a/target/s390x/kvm/kvm.c
>> +++ b/target/s390x/kvm/kvm.c
>> @@ -1576,18 +1576,6 @@ static int handle_sw_breakpoint(S390CPU *cpu,
>> struct kvm_run *run)
>>   return -ENOENT;
>>   }
>>   -void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
>> -{
>> -    CPUS390XState *env = _CPU(cs)->env;
>> -
>> -    /* Feat bit is set only if KVM supports sync for diag318 */
>> -    if (s390_has_feat(S390_FEAT_DIAG_318)) {
>> -    env->diag318_info = diag318_info;
>> -    cs->kvm_run->s.regs.diag318 = diag318_info;
>> -    cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
>> -    }
>> -}
>> -
>>   static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
>>   {
>>   uint64_t reg = (run->s390_sieic.ipa & 0x00f0) >> 4;
>> @@ -1604,8 +1592,11 @@ static void handle_diag_318(S390CPU *cpu,
>> struct kvm_run *run)
>>   }
>>     CPU_FOREACH(t) {
>> -    run_on_cpu(t, s390_do_cpu_set_diag318,
>> -   RUN_ON_CPU_HOST_ULONG(diag318_info));
>> +    CPUS390XState *env = _CPU(t)->env;
>> +
>> +    env->diag318_info = diag318_info;
>> +    t->kvm_run->s.regs.diag318 = diag318_info;
>> +    t->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
> 
> I am not sure if this part works fine. What happens if
> another CPU is currently in SIE (not stopped).
> Then this change will be not visible in that CPU and in
> fact this change will be overwritten when the CPU exits to QEMU.
> 

Ah, I should've paid more attention to what run_on_cpu does. I now see
that it makes CPU changes atomic. I'll reintroduce the helper as a
static function and use the run_on_cpu again.


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH] s390x: kvm: adjust diag318 resets to retain data

2021-11-05 Thread Collin Walling
On 11/5/21 18:46, Collin Walling wrote:
> The CPNC portion of the diag 318 data is erroneously reset during an
> initial CPU reset caused by SIGP. Let's go ahead and relocate the
> diag318_info field within the CPUS390XState struct such that it is
> only zeroed during a clear reset. This way, the CPNC will be retained
> for each VCPU in the configuration after the diag 318 instruction
> has been invoked by the kernel.
> 
> Additionally, the diag 318 data reset is handled via the CPU reset
> code. The set_diag318 code can be merged into the handler function
> and the helper functions can consequently be removed.
> 
> Signed-off-by: Collin Walling 

I neglected to mention that this addresses a bug that was discovered
internally, observed by a recent patch I sent upstream:

[PATCH] KVM: s390x: add debug statement for diag 318 CPNC data

This patch removes most of the code from one of my past patches. Does it
make more sense to revert the old patch and then introduce a follow-up
that includes the additions introduced by this new one?

commit e2c6cd567422bfa563be026b9741a1854aecdc06
Author: Collin L. Walling 
Date:   Fri Nov 13 17:10:22 2020 -0500

s390/kvm: fix diag318 propagation and reset functionality

There is also a bug where hotplugged CPUs are not acquiring the CPNC as
well. I will address a fix to this in a follow-up patch in the future.

-- 
Regards,
Collin

Stay safe and stay healthy



[PATCH] s390x: kvm: adjust diag318 resets to retain data

2021-11-05 Thread Collin Walling
The CPNC portion of the diag 318 data is erroneously reset during an
initial CPU reset caused by SIGP. Let's go ahead and relocate the
diag318_info field within the CPUS390XState struct such that it is
only zeroed during a clear reset. This way, the CPNC will be retained
for each VCPU in the configuration after the diag 318 instruction
has been invoked by the kernel.

Additionally, the diag 318 data reset is handled via the CPU reset
code. The set_diag318 code can be merged into the handler function
and the helper functions can consequently be removed.

Signed-off-by: Collin Walling 
---
 hw/s390x/s390-virtio-ccw.c   |  3 ---
 target/s390x/cpu-sysemu.c|  7 ---
 target/s390x/cpu.h   |  5 ++---
 target/s390x/kvm/kvm.c   | 19 +--
 target/s390x/kvm/kvm_s390x.h |  1 -
 5 files changed, 7 insertions(+), 28 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 653587ea62..51dcb83b0c 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -489,9 +489,6 @@ static void s390_machine_reset(MachineState *machine)
 g_assert_not_reached();
 }
 
-CPU_FOREACH(t) {
-run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
-}
 s390_ipl_clear_reset_request();
 }
 
diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
index 5471e01ee8..6d9f6d4402 100644
--- a/target/s390x/cpu-sysemu.c
+++ b/target/s390x/cpu-sysemu.c
@@ -299,10 +299,3 @@ void s390_enable_css_support(S390CPU *cpu)
 kvm_s390_enable_css_support(cpu);
 }
 }
-
-void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
-{
-if (kvm_enabled()) {
-kvm_s390_set_diag318(cs, arg.host_ulong);
-}
-}
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 3153d053e9..1b94b91d87 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -63,6 +63,8 @@ struct CPUS390XState {
 uint64_t etoken;   /* etoken */
 uint64_t etoken_extension; /* etoken extension */
 
+uint64_t diag318_info;
+
 /* Fields up to this point are not cleared by initial CPU reset */
 struct {} start_initial_reset_fields;
 
@@ -118,8 +120,6 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
-uint64_t diag318_info;
-
 #if !defined(CONFIG_USER_ONLY)
 uint64_t tlb_fill_tec;   /* translation exception code during tlb_fill */
 int tlb_fill_exc;/* exception number seen during tlb_fill */
@@ -780,7 +780,6 @@ int s390_set_memory_limit(uint64_t new_limit, uint64_t 
*hw_limit);
 void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
 void s390_cmma_reset(void);
 void s390_enable_css_support(S390CPU *cpu);
-void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
 int vq, bool assign);
 #ifndef CONFIG_USER_ONLY
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 5b1fdb55c4..ed9c477b6f 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -1576,18 +1576,6 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct 
kvm_run *run)
 return -ENOENT;
 }
 
-void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
-{
-CPUS390XState *env = _CPU(cs)->env;
-
-/* Feat bit is set only if KVM supports sync for diag318 */
-if (s390_has_feat(S390_FEAT_DIAG_318)) {
-env->diag318_info = diag318_info;
-cs->kvm_run->s.regs.diag318 = diag318_info;
-cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
-}
-}
-
 static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
 {
 uint64_t reg = (run->s390_sieic.ipa & 0x00f0) >> 4;
@@ -1604,8 +1592,11 @@ static void handle_diag_318(S390CPU *cpu, struct kvm_run 
*run)
 }
 
 CPU_FOREACH(t) {
-run_on_cpu(t, s390_do_cpu_set_diag318,
-   RUN_ON_CPU_HOST_ULONG(diag318_info));
+CPUS390XState *env = _CPU(t)->env;
+
+env->diag318_info = diag318_info;
+t->kvm_run->s.regs.diag318 = diag318_info;
+t->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
 }
 }
 
diff --git a/target/s390x/kvm/kvm_s390x.h b/target/s390x/kvm/kvm_s390x.h
index 05a5e1e6f4..8c244ee84d 100644
--- a/target/s390x/kvm/kvm_s390x.h
+++ b/target/s390x/kvm/kvm_s390x.h
@@ -44,6 +44,5 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error 
**errp);
 void kvm_s390_crypto_reset(void);
 void kvm_s390_restart_interrupt(S390CPU *cpu);
 void kvm_s390_stop_interrupt(S390CPU *cpu);
-void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info);
 
 #endif /* KVM_S390X_H */
-- 
2.31.1




Re: [PATCH v3] s390/kvm: fix diag318 propagation and reset functionality

2020-11-16 Thread Collin Walling
On 11/16/20 7:12 AM, Cornelia Huck wrote:
> On Fri, 13 Nov 2020 17:10:22 -0500
> Collin Walling  wrote:
> 
> [please remember to put qemu-devel on cc: as well]
> 
>> The Control Program Name Code (CPNC) portion of the diag318
>> info must be set within the SIE block of each VCPU in the
>> configuration. The handler will iterate through each VCPU
>> and dirty the diag318_info reg to be synced with KVM on a
>> subsequent sync_regs call.
>>
>> Additionally, the diag318 info resets must be handled via
>> userspace. As such, QEMU will reset this value for each
>> VCPU during a modified clear, load normal, and load clear
>> reset event.
>>
>> Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
>> Signed-off-by: Collin Walling 
>> ---
>>
>> Changelog:
>>
>> v3:
>> - moved loop outside of switch block
>> - added kvm_s390_set_diag318 function, called by
>> do_cpu_function (this is so other archs do
>> not complain)
>>
>> v2:
>> - added Fixes tag
>> - added CPU feat check in do_cpu function
>>
>> ---
>>  hw/s390x/s390-virtio-ccw.c |  4 
>>  target/s390x/cpu.c |  7 +++
>>  target/s390x/cpu.h |  1 +
>>  target/s390x/kvm-stub.c|  4 
>>  target/s390x/kvm.c | 22 +-
>>  target/s390x/kvm_s390x.h   |  1 +
>>  6 files changed, 34 insertions(+), 5 deletions(-)
> 
> Thanks, queued to s390-fixes.
> 
> I plan to send a pull request tomorrow.
> 
> 

Much appreciated.

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v2 0/2] s390x: pv: Diag318 fixes

2020-10-22 Thread Collin Walling
On 10/22/20 6:31 AM, Janosch Frank wrote:
> Here are two fixes for the diag318 support that fix crashes when
> booting PV guests.
> 
> We're working on extending our testing to catch problems like these
> earlier.
> 
> 
> Branch:
> https://gitlab.com/frankja/qemu/-/commits/bb/frankja/diag318_fixes
> 
> CI:
> https://gitlab.com/frankja/qemu/-/pipelines/206174979
> 
> 
> V2:
>   * Moved fencing nto cpu model functions
>   * Added rev-by and acks
> 
> 
> Janosch Frank (2):
>   s390x: pv: Remove sclp boundary checks
>   s390x: pv: Fix diag318 PV fencing
> 
>  hw/s390x/sclp.c | 5 -
>  target/s390x/cpu_features.c | 5 +
>  target/s390x/cpu_features.h | 4 
>  target/s390x/cpu_models.c   | 4 
>  target/s390x/kvm.c  | 3 +--
>  5 files changed, 14 insertions(+), 7 deletions(-)
> 

Thanks for correcting this. You've certainly received plenty of reviews
and ack's, but since this touches code I worked on:

Reviewed-by: Collin Walling 

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v6 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-25 Thread Collin Walling
On 9/16/20 1:15 PM, Collin Walling wrote:
> On 9/16/20 11:53 AM, Cornelia Huck wrote:
> 
> [...]
> 
>>>
>>
>> Thanks, applied.
>>
>>
> 
> Thanks Conny.
> 
> Much appreciated for everyone's patience and review. The only thing I'd
> like to hold out on for now is for someone to take a peek at patch #3
> with respect to the protected virtualization stuff. I don't know too
> much about it, honestly, and I want to ensure that dynamically
> allocating memory for the SCCB makes sense there. The alternative would
> be to allocate a static 4K for the work_sccb.
> 

I had someone take a look at the patch for PV and was told everything
looks sane. Since the patches have already been applied, it seems like
it's too late to add a reviewed-by from someone?

Either way: thanks to everyone for the journey on getting these patches
through!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v6 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-16 Thread Collin Walling
On 9/16/20 11:53 AM, Cornelia Huck wrote:

[...]

>>
> 
> Thanks, applied.
> 
> 

Thanks Conny.

Much appreciated for everyone's patience and review. The only thing I'd
like to hold out on for now is for someone to take a peek at patch #3
with respect to the protected virtualization stuff. I don't know too
much about it, honestly, and I want to ensure that dynamically
allocating memory for the SCCB makes sense there. The alternative would
be to allocate a static 4K for the work_sccb.

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v6 2/8] s390/sclp: rework sclp boundary checks

2020-09-16 Thread Collin Walling
On 9/16/20 3:10 AM, Thomas Huth wrote:
> On 15/09/2020 21.44, Collin Walling wrote:
>> Rework the SCLP boundary check to account for different SCLP commands
>> (eventually) allowing different boundary sizes.
>>
>> Signed-off-by: Collin Walling 
>> Acked-by: Janosch Frank 
>> Reviewed-by: Cornelia Huck 
>> ---
>>  hw/s390x/sclp.c | 19 ++-
>>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> Reviewed-by: Thomas Huth 
> 

Thanks for the reviews and ack's

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v6 7/8] s390/kvm: header sync for diag318

2020-09-16 Thread Collin Walling
On 9/16/20 11:52 AM, Cornelia Huck wrote:
> On Tue, 15 Sep 2020 15:44:15 -0400
> Collin Walling  wrote:
> 
>> Signed-off-by: Collin Walling 
>> ---
>>  linux-headers/asm-s390/kvm.h | 7 +--
>>  linux-headers/linux/kvm.h| 1 +
>>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> I've replaced this with an update against 5.9-rc5.
> 
> 

Thanks, Conny

-- 
Regards,
Collin

Stay safe and stay healthy



[PATCH v6 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-09-15 Thread Collin Walling
As more features and facilities are added to the Read SCP Info (RSCPI)
response, more space is required to store them. The space used to store
these new features intrudes on the space originally used to store CPU
entries. This means as more features and facilities are added to the
RSCPI response, less space can be used to store CPU entries.

With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
the RSCPI command and determine if the SCCB is large enough to store a
complete reponse. If it is not large enough, then the required length
will be set in the SCCB header.

The caller of the SCLP command is responsible for creating a
large-enough SCCB to store a complete response. Proper checking should
be in place, and the caller should execute the command once-more with
the large-enough SCCB.

This facility also enables an extended SCCB for the Read CPU Info
(RCPUI) command.

When this facility is enabled, the boundary violation response cannot
be a result from the RSCPI, RSCPI Forced, or RCPUI commands.

In order to tolerate kernels that do not yet have full support for this
feature, a "fixed" offset to the start of the CPU Entries within the
Read SCP Info struct is set to allow for the original 248 max entries
when this feature is disabled.

Additionally, this is introduced as a CPU feature to protect the guest
from migrating to a machine that does not support storing an extended
SCCB. This could otherwise hinder the VM from being able to read all
available CPU entries after migration (such as during re-ipl).

Signed-off-by: Collin Walling 
Acked-by: Cornelia Huck 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 43 +
 include/hw/s390x/sclp.h |  1 +
 target/s390x/cpu_features_def.h.inc |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  |  8 ++
 5 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 1df67c99bf..caf40f41b6 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,13 +49,30 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len)
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len,
+ uint32_t code)
 {
 uint64_t sccb_max_addr = sccb_addr + sccb_len - 1;
 uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
 
-if (sccb_max_addr < sccb_boundary) {
-return true;
+switch (code & SCLP_CMD_CODE_MASK) {
+case SCLP_CMDW_READ_SCP_INFO:
+case SCLP_CMDW_READ_SCP_INFO_FORCED:
+case SCLP_CMDW_READ_CPU_INFO:
+/*
+ * An extended-length SCCB is only allowed for Read SCP/CPU Info and
+ * is allowed to exceed the 4k boundary. The respective commands will
+ * set the length field to the required length if an insufficient
+ * SCCB length is provided.
+ */
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+return true;
+}
+/* fallthrough */
+default:
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
 }
 
 return false;
@@ -80,6 +97,12 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 
 #define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
 
+static inline bool ext_len_sccb_supported(SCCBHeader header)
+{
+return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
+   header.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE;
+}
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -89,10 +112,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
-int offset_cpu = offsetof(ReadInfo, entries);
+int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
+ offsetof(ReadInfo, entries) :
+ SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
 CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
+if (ext_len_sccb_supported(sccb->h)) {
+sccb->h.length = cpu_to_be16(required_len);
+}
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
 return;
 }
@@ -153,6 +181,9 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
+if (ext_len_sccb_supported(sccb->h)) {
+sccb->h.length = cpu_to_be16(required_len);
+}
 sccb->h.

[PATCH v6 7/8] s390/kvm: header sync for diag318

2020-09-15 Thread Collin Walling
Signed-off-by: Collin Walling 
---
 linux-headers/asm-s390/kvm.h | 7 +--
 linux-headers/linux/kvm.h| 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 0138ccb0d8..f053b8304a 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+#define KVM_SYNC_DIAG318 (1UL << 12)
 
 #define KVM_SYNC_S390_VALID_FIELDS \
(KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
 KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
-KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
+KVM_SYNC_DIAG318)
 
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
@@ -264,7 +266,8 @@ struct kvm_sync_regs {
__u8 reserved2 : 7;
__u8 padding1[51];  /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */
-   __u8 padding2[192]; /* sdnx needs to be 256byte aligned */
+   __u64 diag318;  /* diagnose 0x318 info */
+   __u8 padding2[184]; /* sdnx needs to be 256byte aligned */
union {
__u8 sdnx[SDNXL];  /* state description annex */
struct {
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index a28c366737..a789bfb5a2 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1031,6 +1031,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_SECURE_GUEST 181
 #define KVM_CAP_HALT_POLL 182
 #define KVM_CAP_ASYNC_PF_INT 183
+#define KVM_CAP_S390_DIAG318 184
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.26.2




[PATCH v6 2/8] s390/sclp: rework sclp boundary checks

2020-09-15 Thread Collin Walling
Rework the SCLP boundary check to account for different SCLP commands
(eventually) allowing different boundary sizes.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 28b973de8f..a37cfbf534 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,6 +49,18 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t sccb_len)
+{
+uint64_t sccb_max_addr = sccb_addr + sccb_len - 1;
+uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
+
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
+
+return false;
+}
+
 static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
@@ -229,6 +241,11 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb.h.length))) {
+work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+goto out_write;
+}
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -274,7 +291,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
-if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + 
PAGE_SIZE)) {
+if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb.h.length))) {
 work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
-- 
2.26.2




[PATCH v6 4/8] s390/sclp: check sccb len before filling in data

2020-09-15 Thread Collin Walling
The SCCB must be checked for a sufficient length before it is filled
with any data. If the length is insufficient, then the SCLP command
is suppressed and the proper response code is set in the SCCB header.

While we're at it, let's cleanup the length check by placing the
calculation inside a macro.

Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length")
Signed-off-by: Collin Walling 
Reviewed-by: Janosch Frank 
Reviewed-by: David Hildenbrand 
Reviewed-by: Cornelia Huck 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 4ae6fb400b..0d54075309 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -78,6 +78,8 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 }
 }
 
+#define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -86,6 +88,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int cpu_count;
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
+int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
 
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
@@ -95,12 +103,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* Configuration Characteristic (Extension) */
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
  read_info->conf_char);
@@ -146,18 +148,18 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
+int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
 
 prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* The standby offset is 16-byte for each CPU */
 cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
 + cpu_info->nr_configured*sizeof(CPUEntry));
-- 
2.26.2




[PATCH v6 5/8] s390/sclp: use cpu offset to locate cpu entries

2020-09-15 Thread Collin Walling
The start of the CPU entry region in the Read SCP Info response data is
denoted by the offset_cpu field. As such, QEMU needs to begin creating
entries at this address.

This is in preparation for when Read SCP Info inevitably introduces new
bytes that push the start of the CPUEntry field further away.

Read CPU Info is unlikely to ever change, so let's not bother
accounting for the offset there.

Signed-off-by: Collin Walling 
Reviewed-by: Thomas Huth 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 0d54075309..1df67c99bf 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -89,6 +89,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
+int offset_cpu = offsetof(ReadInfo, entries);
+CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
@@ -96,9 +98,9 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 }
 
 /* CPU information */
-prepare_cpu_entries(machine, read_info->entries, _count);
+prepare_cpu_entries(machine, entries_start, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
-read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
+read_info->offset_cpu = cpu_to_be16(offset_cpu);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
-- 
2.26.2




[PATCH v6 1/8] s390/sclp: get machine once during read scp/cpu info

2020-09-15 Thread Collin Walling
Functions within read scp/cpu info will need access to the machine
state. Let's make a call to retrieve the machine state once and
pass the appropriate data to the respective functions.

Signed-off-by: Collin Walling 
Reviewed-by: David Hildenbrand 
Reviewed-by: Thomas Huth 
Reviewed-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index a0ce444b4b..28b973de8f 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,9 +49,8 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
+static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
 int i;
 
@@ -77,7 +76,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
 /* CPU information */
-prepare_cpu_entries(sclp, read_info->entries, _count);
+prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
@@ -132,10 +131,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 /* Provide information about the CPU */
 static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 {
+MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(sclp, cpu_info->entries, _count);
+prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
-- 
2.26.2




[PATCH v6 8/8] s390: guest support for diagnose 0x318

2020-09-15 Thread Collin Walling
DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
of diagnostic information that is collected by the firmware in the case
of hardware/firmware service events.

QEMU handles the instruction by storing the info in the CPU state. A
subsequent register sync will communicate the data to the hypervisor.

QEMU handles the migration via a VM State Description.

This feature depends on the Extended-Length SCCB (els) feature. If
els is not present, then a warning will be printed and the SCLP bit
that allows the Linux kernel to execute the instruction will not be
set.

Availability of this instruction is determined by byte 134 (aka fac134)
bit 0 of the SCLP Read Info block. This coincidentally expands into the
space used for CPU entries, which means VMs running with the diag318
capability may not be able to read information regarding all CPUs
unless the guest kernel supports an extended-length SCCB.

This feature is not supported in protected virtualization mode.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
---
 hw/s390x/sclp.c |  5 
 include/hw/s390x/sclp.h |  8 ++
 target/s390x/cpu.h  |  2 ++
 target/s390x/cpu_features.h |  1 +
 target/s390x/cpu_features_def.h.inc |  3 +++
 target/s390x/cpu_models.c   |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  | 39 +
 target/s390x/machine.c  | 17 +
 9 files changed, 77 insertions(+)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index caf40f41b6..00f1e4648d 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -139,6 +139,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
  read_info->conf_char_ext);
 
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
+_info->fac134);
+}
+
 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 141e57f765..c84eb8ac65 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -133,7 +133,15 @@ typedef struct ReadInfo {
 uint16_t highest_cpu;
 uint8_t  _reserved5[124 - 122]; /* 122-123 */
 uint32_t hmfai;
+uint8_t  _reserved7[134 - 128]; /* 128-133 */
+uint8_t  fac134;
+uint8_t  _reserved8[144 - 135]; /* 135-143 */
 struct CPUEntry entries[];
+/*
+ * When the Extended-Length SCCB (ELS) feature is enabled the
+ * start of the entries field begins at an offset denoted by the
+ * offset_cpu field, otherwise it's at an offset of 128.
+ */
 } QEMU_PACKED ReadInfo;
 
 typedef struct ReadCpuInfo {
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 035427521c..f875ebf0f4 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -112,6 +112,8 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
+uint64_t diag318_info;
+
 /* Fields up to this point are cleared by a CPU reset */
 struct {} end_reset_fields;
 
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index 2a29475493..ef52ffce83 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_FAC134,
 S390_FEAT_TYPE_SCLP_CPU,
 S390_FEAT_TYPE_MISC,
 S390_FEAT_TYPE_PLO,
diff --git a/target/s390x/cpu_features_def.h.inc 
b/target/s390x/cpu_features_def.h.inc
index 1c04cc18f4..f82b4b5ec1 100644
--- a/target/s390x/cpu_features_def.h.inc
+++ b/target/s390x/cpu_features_def.h.inc
@@ -122,6 +122,9 @@ DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: 
Collaborative-memory-man
 DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation 
facility")
 DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: 
Interlock-and-broadcast-suppression facility")
 
+/* Features exposed via SCLP SCCB Facilities byte 134 (bit numbers relative to 
byte-134) */
+DEF_FEAT(DIAG_318, "diag318", SCLP_FAC134, 0, "Control program name and 
version codes")
+
 /* Features exposed via SCLP CPU info. */
 DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual 
SIE)")
 DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index c2af226174..9d615f13e7 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -824,6 +824,7 @@ static void check_consistency(const S390CPUModel *

[PATCH v6 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-15 Thread Collin Walling
Changelog:

v6

• sccb_verify_boundary function:
• s/len/sccb_len
• removed the endian check/conversion of the sccb_len from within 
  this function (caller is now responsible)

• proper endian conversion when using header length to malloc

• use g_autofree for work_sccb

• added r-b's and acks (thanks!)

• added a feature-check fence within the diag_318_handler to ensure
the handler does not complete without proper feature support
• will throw a program exception if handler is invoked but
  feature is not enabled



v5 (comment below pertains to version 5)

Janosch, Thomas, Conny: I've removed your r-b's from patch #3 since I
added some g_mallocs in place and I'd like to make sure things are
done properly there (explained in changelog, but let me know if further
explanation is necessary).

Janosch, please let me know if the changes to #3 are safe under PV.

Thanks.

• removed sccb_verify_length function
- will simply use the length check code that was in place before

• introduced a macro for calculating required SCCB length
- takes a struct and max # of cpus as args

• work_sccb size is now dynamically allocated based on the length
  provided by the guest kernel, instead of always using a static
  4K size
- as such, the SCCB will have to be read twice:
- first time to retrieve the header
- second time with proper size after space for work_sccb 
  is allocated



v4

• added r-b's and ack's (thanks, everyone!)

• renamed boundary and length function

• updated header sync to reflect a change discussed in the respective
KVM patches

• s/data_len/offset_cpu

• added /* fallthrough */ comment in boundary check



v3

• Device IOCTLs removed
- diag 318 info is now communicated via sync_regs

• Reset code removed
- this is now handled in KVM
- diag318_info is stored within the CPU reset portion of the
S390CPUState

• Various cleanups for ELS preliminary patches



v2

• QEMU now handles the instruction call
- as such, the "enable diag 318" IOCTL has been removed

• patch #1 now changes the read scp/cpu info functions to
  retrieve the machine state once
- as such, I have not added any ack's or r-bs since this
  patch differs from the previous version

• patch #3 introduces a new "get_read_scp_info_data_len"
  function in order clean-up the variable data length assignment
  in patch #7
- a comment above this function should help clarify what's
  going on to make things a bit easier to read

• other misc clean ups and fixes
- s/diag318/diag_318 in order to keep the naming scheme
  consistent with Linux and other diag-related code
- s/byte_134/fac134 to align naming scheme with Linux

---

This patch series introduces two features for an s390 KVM quest:
- Extended-Length SCCB (els) for the Read SCP/CPU Info SCLP 
commands
- DIAGNOSE 0x318 (diag_318) enabling / migration handling

The diag 318 feature depends on els and KVM support.

The els feature is handled entirely with QEMU, and does not require 
KVM support.

Both features are made available starting with the zEC12-full model.

These patches are introduced together for two main reasons:
- els allows diag 318 to exist while retaining the original 248 
VCPU max
- diag 318 is presented to show how els is useful

Full els support is dependant on the Linux kernel, which must react
to the SCLP response code and set an appropriate-length SCCB. 

A user should take care when tuning the CPU model for a VM.
If a user defines a VM with els support and specifies 248 CPUs, but
the guest Linux kernel cannot react to the SCLP response code, then
the guest will crash immediately upon kernel startup.

Collin L. Walling (8):
  s390/sclp: get machine once during read scp/cpu info
  s390/sclp: rework sclp boundary checks
  s390/sclp: read sccb from mem based on provided length
  s390/sclp: check sccb len before filling in data
  s390/sclp: use cpu offset to locate cpu entries
  s390/sclp: add extended-length sccb support for kvm guest
  s390/kvm: header sync for diag318
  s390: guest support for diagnose 0x318

 hw/s390x/event-facility.c   |   2 +-
 hw/s390x/sclp.c | 142 
 include/hw/s390x/sclp.h |  11 ++-
 linux-headers/asm-s390/kvm.h|   7 +-
 linux-headers/linux/kvm.h   |   1 +
 target/s390x/cpu.h  |   2 +
 target/s390x/cpu_features.h |   1 +
 target/s390x/cpu_features_def.h.inc |   4 +
 target/s390x/cpu_models.c   |   1 +
 target/s390x/gen-features.c |   2 +
 target/s390x/kvm.c 

[PATCH v6 3/8] s390/sclp: read sccb from mem based on provided length

2020-09-15 Thread Collin Walling
The header contained within the SCCB passed to the SCLP service call
contains the actual length of the SCCB. Instead of allocating a static
4K size for the work sccb, let's allow for a variable size determined
by the value in the header. The proper checks are already in place to
ensure the SCCB length is sufficent to store a full response and that
the length does not cross any explicitly-set boundaries.

Signed-off-by: Collin Walling 
---
 hw/s390x/event-facility.c |  2 +-
 hw/s390x/sclp.c   | 55 ++-
 include/hw/s390x/sclp.h   |  2 +-
 3 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 645b4080c5..ed92ce510d 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -213,7 +213,7 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility 
*ef, SCCB *sccb,
 
 event_buf = >ebh;
 event_buf->length = 0;
-slen = sizeof(sccb->data);
+slen = sccb_data_len(sccb);
 
 rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
 
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index a37cfbf534..4ae6fb400b 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -231,25 +231,29 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 {
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
-SCCB work_sccb;
-hwaddr sccb_len = sizeof(SCCB);
+SCCBHeader header;
+g_autofree SCCB *work_sccb = NULL;
 
-s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
+s390_cpu_pv_mem_read(env_archcpu(env), 0, , sizeof(SCCBHeader));
+
+work_sccb = g_malloc0(be16_to_cpu(header.length));
+s390_cpu_pv_mem_read(env_archcpu(env), 0, work_sccb,
+ be16_to_cpu(header.length));
 
 if (!sclp_command_code_valid(code)) {
-work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 goto out_write;
 }
 
-if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb.h.length))) {
-work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length))) {
+work_sccb->h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
 
-sclp_c->execute(sclp, _sccb, code);
+sclp_c->execute(sclp, work_sccb, code);
 out_write:
-s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
-  be16_to_cpu(work_sccb.h.length));
+s390_cpu_pv_mem_write(env_archcpu(env), 0, work_sccb,
+  be16_to_cpu(work_sccb->h.length));
 sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
 return 0;
 }
@@ -258,9 +262,8 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 {
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
-SCCB work_sccb;
-
-hwaddr sccb_len = sizeof(SCCB);
+SCCBHeader header;
+g_autofree SCCB *work_sccb = NULL;
 
 /* first some basic checks on program checks */
 if (env->psw.mask & PSW_MASK_PSTATE) {
@@ -274,32 +277,36 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 return -PGM_SPECIFICATION;
 }
 
+/* the header contains the actual length of the sccb */
+cpu_physical_memory_read(sccb, , sizeof(SCCBHeader));
+
+/* Valid sccb sizes */
+if (be16_to_cpu(header.length) < sizeof(SCCBHeader)) {
+return -PGM_SPECIFICATION;
+}
+
 /*
  * we want to work on a private copy of the sccb, to prevent guests
  * from playing dirty tricks by modifying the memory content after
  * the host has checked the values
  */
-cpu_physical_memory_read(sccb, _sccb, sccb_len);
-
-/* Valid sccb sizes */
-if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
-return -PGM_SPECIFICATION;
-}
+work_sccb = g_malloc0(be16_to_cpu(header.length));
+cpu_physical_memory_read(sccb, work_sccb, be16_to_cpu(header.length));
 
 if (!sclp_command_code_valid(code)) {
-work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 goto out_write;
 }
 
-if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb.h.length))) {
-work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+if (!sccb_verify_boundary(sccb, be16_to_cpu(work_sccb->h.length))) {
+work_sccb->h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
 
-sclp_c->execute(sclp, _sccb, code);
+sclp_c->execute(sclp, work_sccb, code);
 out_write:
-cpu_physical_memory_write(sccb, _sccb,
-  be16_to_cpu(work_sccb.

Re: [PATCH v5 8/8] s390: guest support for diagnose 0x318

2020-09-15 Thread Collin Walling
On 9/11/20 11:08 AM, Thomas Huth wrote:
> On 10/09/2020 11.36, Collin Walling wrote:
>> DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
>> of diagnostic information that is collected by the firmware in the case
>> of hardware/firmware service events.
>>
>> QEMU handles the instruction by storing the info in the CPU state. A
>> subsequent register sync will communicate the data to the hypervisor.
>>
>> QEMU handles the migration via a VM State Description.
>>
>> This feature depends on the Extended-Length SCCB (els) feature. If
>> els is not present, then a warning will be printed and the SCLP bit
>> that allows the Linux kernel to execute the instruction will not be
>> set.
>>
>> Availability of this instruction is determined by byte 134 (aka fac134)
>> bit 0 of the SCLP Read Info block. This coincidentally expands into the
>> space used for CPU entries, which means VMs running with the diag318
>> capability may not be able to read information regarding all CPUs
>> unless the guest kernel supports an extended-length SCCB.
>>
>> This feature is not supported in protected virtualization mode.
>>
>> Signed-off-by: Collin Walling 
>> Acked-by: Janosch Frank 
>> ---
>>  hw/s390x/sclp.c |  5 +
>>  include/hw/s390x/sclp.h |  3 +++
>>  target/s390x/cpu.h  |  2 ++
>>  target/s390x/cpu_features.h |  1 +
>>  target/s390x/cpu_features_def.h.inc |  3 +++
>>  target/s390x/cpu_models.c   |  1 +
>>  target/s390x/gen-features.c |  1 +
>>  target/s390x/kvm.c  | 31 +
>>  target/s390x/machine.c  | 17 
>>  9 files changed, 64 insertions(+)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 87d468087b..ad5d70e14d 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -139,6 +139,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
>>   read_info->conf_char_ext);
>>  
>> +if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
>> +s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
>> +_info->fac134);
>> +}
> 
> Wasn't this feature also possible if there are less than 240 CPUs? Or do
> I mix that up with something else? ... well, maybe it's best anyway if
> we only allow this when ELS is enabled.
> 
>>  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 141e57f765..516f949109 100644
>> --- a/include/hw/s390x/sclp.h
>> +++ b/include/hw/s390x/sclp.h
>> @@ -133,6 +133,9 @@ typedef struct ReadInfo {
>>  uint16_t highest_cpu;
>>  uint8_t  _reserved5[124 - 122]; /* 122-123 */
>>  uint32_t hmfai;
>> +uint8_t  _reserved7[134 - 128]; /* 128-133 */
>> +uint8_t  fac134;
>> +uint8_t  _reserved8[144 - 135]; /* 135-143 */
>>  struct CPUEntry entries[];
> 
> Could you please add a comment after entries[] like,
> 
>  /* only here with "ELS", it's at offset 128 otherwise */
> 
> ?
> 
>>  } QEMU_PACKED ReadInfo;
>>  
> [...]
>>  static uint16_t full_GEN12_GA2[] = {
>> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
>> index a2d5ad78f6..b79feeba9f 100644
>> --- a/target/s390x/kvm.c
>> +++ b/target/s390x/kvm.c
>> @@ -105,6 +105,7 @@
>>  
>>  #define DIAG_TIMEREVENT 0x288
>>  #define DIAG_IPL0x308
>> +#define DIAG_SET_CONTROL_PROGRAM_CODES  0x318
>>  #define DIAG_KVM_HYPERCALL  0x500
>>  #define DIAG_KVM_BREAKPOINT 0x501
>>  
>> @@ -602,6 +603,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
>>  cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ETOKEN;
>>  }
>>  
>> +if (can_sync_regs(cs, KVM_SYNC_DIAG318)) {
>> +cs->kvm_run->s.regs.diag318 = env->diag318_info;
>> +cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
>> +}
>> +
>>  /* Finally the prefix */
>>  if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
>>  cs->kvm_run->s.regs.prefix = env->psa;
>> @@ -741,6 +747,10 @@ int kvm_arch_get_registers(CPUState *cs)
>>  }
>>  }
>>  
>> +if (can_sync_regs(c

Re: [PATCH v5 3/8] s390/sclp: read sccb from mem based on provided length

2020-09-15 Thread Collin Walling
On 9/12/20 2:28 AM, Thomas Huth wrote:
> On 11/09/2020 20.16, Collin Walling wrote:
>> On 9/10/20 1:56 PM, Collin Walling wrote:
>>> On 9/10/20 1:50 PM, Thomas Huth wrote:
>>>> On 10/09/2020 11.36, Collin Walling wrote:
>>>>> The header contained within the SCCB passed to the SCLP service call
>>>>> contains the actual length of the SCCB. Instead of allocating a static
>>>>> 4K size for the work sccb, let's allow for a variable size determined
>>>>> by the value in the header. The proper checks are already in place to
>>>>> ensure the SCCB length is sufficent to store a full response and that
>>>>> the length does not cross any explicitly-set boundaries.
>>>>>
>>>>> Signed-off-by: Collin Walling 
>>>>> ---
>>>>>  hw/s390x/event-facility.c |  2 +-
>>>>>  hw/s390x/sclp.c   | 58 ++-
>>>>>  include/hw/s390x/sclp.h   |  2 +-
>>>>>  3 files changed, 35 insertions(+), 27 deletions(-)
>>>>>
>>>>> diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
>>>>> index 645b4080c5..ed92ce510d 100644
>>>>> --- a/hw/s390x/event-facility.c
>>>>> +++ b/hw/s390x/event-facility.c
>>>>> @@ -213,7 +213,7 @@ static uint16_t 
>>>>> handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
>>>>>  
>>>>>  event_buf = >ebh;
>>>>>  event_buf->length = 0;
>>>>> -slen = sizeof(sccb->data);
>>>>> +slen = sccb_data_len(sccb);
>>>>>  
>>>>>  rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
>>>>>  
>>>>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>>>>> index 69a8724dc7..cb8e2e8ec3 100644
>>>>> --- a/hw/s390x/sclp.c
>>>>> +++ b/hw/s390x/sclp.c
>>>>> @@ -231,25 +231,30 @@ int sclp_service_call_protected(CPUS390XState *env, 
>>>>> uint64_t sccb,
>>>>>  {
>>>>>  SCLPDevice *sclp = get_sclp_device();
>>>>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>>>>> -SCCB work_sccb;
>>>>> -hwaddr sccb_len = sizeof(SCCB);
>>>>> +SCCBHeader header;
>>>>> +SCCB *work_sccb;
>>>>
>>>> I'd maybe use "g_autofree SCCB *work_sccb = NULL" so you don't have to
>>>> worry about doing the g_free() later.
>>>
>>> Can do.
>>>
>>>>
>>>>> -s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
>>>>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, , 
>>>>> sizeof(SCCBHeader));
>>>>> +
>>>>> +work_sccb = g_malloc0(header.length);
>>>>
>>>> Please use be16_to_cpu(header.length) here as well.
>>>
>>> Good catch, thanks!
>>>
>>
>> Shouldn't the mallocs use cpu_to_be16 instead since the header length
>> was read in from a cpu?
> 
> Now you confuse me ... s390x is big endian, so to get a usable value, we
> have to convert big-endian to the host byte order, not the other way
> round, don't we?
> 
>  Thomas
> 
> 

Err, yes you're right.

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v5 3/8] s390/sclp: read sccb from mem based on provided length

2020-09-11 Thread Collin Walling
On 9/10/20 1:56 PM, Collin Walling wrote:
> On 9/10/20 1:50 PM, Thomas Huth wrote:
>> On 10/09/2020 11.36, Collin Walling wrote:
>>> The header contained within the SCCB passed to the SCLP service call
>>> contains the actual length of the SCCB. Instead of allocating a static
>>> 4K size for the work sccb, let's allow for a variable size determined
>>> by the value in the header. The proper checks are already in place to
>>> ensure the SCCB length is sufficent to store a full response and that
>>> the length does not cross any explicitly-set boundaries.
>>>
>>> Signed-off-by: Collin Walling 
>>> ---
>>>  hw/s390x/event-facility.c |  2 +-
>>>  hw/s390x/sclp.c   | 58 ++-
>>>  include/hw/s390x/sclp.h   |  2 +-
>>>  3 files changed, 35 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
>>> index 645b4080c5..ed92ce510d 100644
>>> --- a/hw/s390x/event-facility.c
>>> +++ b/hw/s390x/event-facility.c
>>> @@ -213,7 +213,7 @@ static uint16_t 
>>> handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
>>>  
>>>  event_buf = >ebh;
>>>  event_buf->length = 0;
>>> -slen = sizeof(sccb->data);
>>> +slen = sccb_data_len(sccb);
>>>  
>>>  rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
>>>  
>>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>>> index 69a8724dc7..cb8e2e8ec3 100644
>>> --- a/hw/s390x/sclp.c
>>> +++ b/hw/s390x/sclp.c
>>> @@ -231,25 +231,30 @@ int sclp_service_call_protected(CPUS390XState *env, 
>>> uint64_t sccb,
>>>  {
>>>  SCLPDevice *sclp = get_sclp_device();
>>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>>> -SCCB work_sccb;
>>> -hwaddr sccb_len = sizeof(SCCB);
>>> +SCCBHeader header;
>>> +SCCB *work_sccb;
>>
>> I'd maybe use "g_autofree SCCB *work_sccb = NULL" so you don't have to
>> worry about doing the g_free() later.
> 
> Can do.
> 
>>
>>> -s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
>>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, , sizeof(SCCBHeader));
>>> +
>>> +work_sccb = g_malloc0(header.length);
>>
>> Please use be16_to_cpu(header.length) here as well.
> 
> Good catch, thanks!
> 

Shouldn't the mallocs use cpu_to_be16 instead since the header length
was read in from a cpu?

[...]

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v5 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-09-11 Thread Collin Walling
On 9/11/20 9:54 AM, Thomas Huth wrote:
> On 11/09/2020 15.41, Thomas Huth wrote:
>> On 10/09/2020 11.36, Collin Walling wrote:
>>> As more features and facilities are added to the Read SCP Info (RSCPI)
>>> response, more space is required to store them. The space used to store
>>> these new features intrudes on the space originally used to store CPU
>>> entries. This means as more features and facilities are added to the
>>> RSCPI response, less space can be used to store CPU entries.
>>>
>>> With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
>>> the RSCPI command and determine if the SCCB is large enough to store a
>>> complete reponse. If it is not large enough, then the required length
>>> will be set in the SCCB header.
>>>
>>> The caller of the SCLP command is responsible for creating a
>>> large-enough SCCB to store a complete response. Proper checking should
>>> be in place, and the caller should execute the command once-more with
>>> the large-enough SCCB.
>>>
>>> This facility also enables an extended SCCB for the Read CPU Info
>>> (RCPUI) command.
>>>
>>> When this facility is enabled, the boundary violation response cannot
>>> be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
>>>
>>> In order to tolerate kernels that do not yet have full support for this
>>> feature, a "fixed" offset to the start of the CPU Entries within the
>>> Read SCP Info struct is set to allow for the original 248 max entries
>>> when this feature is disabled.
>>>
>>> Additionally, this is introduced as a CPU feature to protect the guest
>>> from migrating to a machine that does not support storing an extended
>>> SCCB. This could otherwise hinder the VM from being able to read all
>>> available CPU entries after migration (such as during re-ipl).
>>>
>>> Signed-off-by: Collin Walling 
>>> ---
>> [...]
>>>  /* Provide information about the configuration, CPUs and storage */
>>>  static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>>  {
>>> @@ -89,10 +112,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>>  int rnsize, rnmax;
>>>  IplParameterBlock *ipib = s390_ipl_get_iplb();
>>>  int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
>>> -int offset_cpu = offsetof(ReadInfo, entries);
>>> +int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
>>> + offsetof(ReadInfo, entries) :
>>> + SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
>>
>> Sorry, but I'm having somewhat trouble to understand this...
>> What's the difference between offsetof(ReadInfo, entries) and
>> SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET ? Aren't both terms resulting in the
>> value 128 ?
> 
> Ah, well, the answer is clear after looking at patch 8/8 ... ReadInfo is
> extended there, so offsetof(ReadInfo, entries) will result in a
> different value.
> Might have been better to move the above hunk into patch 8/8, but if you
> want to keep it here, that's now ok for me, too.
> 
> Reviewed-by: Thomas Huth 
> 
> 

I see your point. In retrospect, it might've been better to include it
in patch 8/8 so it's more clear why these features are introduced within
the same patch set.

If there are any requests to change / fixup this patch in any other
regard, then I'll consider moving the offset_cpu calculation to 8/8.

Otherwise, I'll leave it here :)

Thanks!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v5 2/8] s390/sclp: rework sclp boundary checks

2020-09-11 Thread Collin Walling
On 9/11/20 6:24 AM, Cornelia Huck wrote:
> On Thu, 10 Sep 2020 19:45:01 +0200
> Thomas Huth  wrote:
> 
>> On 10/09/2020 11.36, Collin Walling wrote:
>>> Rework the SCLP boundary check to account for different SCLP commands
>>> (eventually) allowing different boundary sizes.
>>>
>>> Signed-off-by: Collin Walling 
>>> Acked-by: Janosch Frank 
>>> Reviewed-by: Cornelia Huck 
>>> ---
>>>  hw/s390x/sclp.c | 19 ++-
>>>  1 file changed, 18 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>>> index 28b973de8f..69a8724dc7 100644
>>> --- a/hw/s390x/sclp.c
>>> +++ b/hw/s390x/sclp.c
>>> @@ -49,6 +49,18 @@ static inline bool sclp_command_code_valid(uint32_t code)
>>>  return false;
>>>  }
>>>  
>>> +static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t len)  
>>
>> Maybe it would be good to add a comment in front of the function to say
>> that len must be big endian?
> 
> What about renaming it to sccb_h_len or so? That would make it more
> clear that the parameter is not just some random length.
> 

I think that makes sense.

>>
>>  Thomas
>>
>>> +{
>>> +uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(len) - 1;
>>> +uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>>> +
>>> +if (sccb_max_addr < sccb_boundary) {
>>> +return true;
>>> +}
>>> +
>>> +return false;
>>> +}
>>> +
>>>  static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int 
>>> *count)
>>>  {
>>>  uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
>>> @@ -229,6 +241,11 @@ int sclp_service_call_protected(CPUS390XState *env, 
>>> uint64_t sccb,
>>>  goto out_write;
>>>  }
>>>  
>>> +if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
> 
> ...name inspired by the 'h' in here.
> 
>>> +work_sccb.h.response_code = 
>>> cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>>> +goto out_write;
>>> +}
>>> +
>>>  sclp_c->execute(sclp, _sccb, code);
>>>  out_write:
>>>  s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
>>> @@ -274,7 +291,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t 
>>> sccb, uint32_t code)
>>>  goto out_write;
>>>  }
>>>  
>>> -if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + 
>>> PAGE_SIZE)) {
>>> +if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
>>>  work_sccb.h.response_code = 
>>> cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>>>  goto out_write;
>>>  }
>>>   
>>
> 
> 


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v5 3/8] s390/sclp: read sccb from mem based on provided length

2020-09-10 Thread Collin Walling
On 9/10/20 1:50 PM, Thomas Huth wrote:
> On 10/09/2020 11.36, Collin Walling wrote:
>> The header contained within the SCCB passed to the SCLP service call
>> contains the actual length of the SCCB. Instead of allocating a static
>> 4K size for the work sccb, let's allow for a variable size determined
>> by the value in the header. The proper checks are already in place to
>> ensure the SCCB length is sufficent to store a full response and that
>> the length does not cross any explicitly-set boundaries.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  hw/s390x/event-facility.c |  2 +-
>>  hw/s390x/sclp.c   | 58 ++-
>>  include/hw/s390x/sclp.h   |  2 +-
>>  3 files changed, 35 insertions(+), 27 deletions(-)
>>
>> diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
>> index 645b4080c5..ed92ce510d 100644
>> --- a/hw/s390x/event-facility.c
>> +++ b/hw/s390x/event-facility.c
>> @@ -213,7 +213,7 @@ static uint16_t 
>> handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
>>  
>>  event_buf = >ebh;
>>  event_buf->length = 0;
>> -slen = sizeof(sccb->data);
>> +slen = sccb_data_len(sccb);
>>  
>>  rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
>>  
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 69a8724dc7..cb8e2e8ec3 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -231,25 +231,30 @@ int sclp_service_call_protected(CPUS390XState *env, 
>> uint64_t sccb,
>>  {
>>  SCLPDevice *sclp = get_sclp_device();
>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>> -SCCB work_sccb;
>> -hwaddr sccb_len = sizeof(SCCB);
>> +SCCBHeader header;
>> +SCCB *work_sccb;
> 
> I'd maybe use "g_autofree SCCB *work_sccb = NULL" so you don't have to
> worry about doing the g_free() later.

Can do.

> 
>> -s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, , sizeof(SCCBHeader));
>> +
>> +work_sccb = g_malloc0(header.length);
> 
> Please use be16_to_cpu(header.length) here as well.

Good catch, thanks!

> 
>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, work_sccb,
>> + be16_to_cpu(header.length));
>>  
>>  if (!sclp_command_code_valid(code)) {
>> -work_sccb.h.response_code = 
>> cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
>> +work_sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
>>  goto out_write;
>>  }
>>  
>> -if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
>> -work_sccb.h.response_code = 
>> cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>> +if (!sccb_verify_boundary(sccb, work_sccb->h.length)) {
>> +work_sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>>  goto out_write;
>>  }
>>  
>> -sclp_c->execute(sclp, _sccb, code);
>> +sclp_c->execute(sclp, work_sccb, code);
>>  out_write:
>> -s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
>> -  be16_to_cpu(work_sccb.h.length));
>> +s390_cpu_pv_mem_write(env_archcpu(env), 0, work_sccb,
>> +  be16_to_cpu(work_sccb->h.length));
>> +g_free(work_sccb);
>>  sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
>>  return 0;
>>  }
>> @@ -258,9 +263,8 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
>> uint32_t code)
>>  {
>>  SCLPDevice *sclp = get_sclp_device();
>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>> -SCCB work_sccb;
>> -
>> -hwaddr sccb_len = sizeof(SCCB);
>> +SCCBHeader header;
>> +SCCB *work_sccb;
> 
> Maybe g_autofree again?
> 
>>  /* first some basic checks on program checks */
>>  if (env->psw.mask & PSW_MASK_PSTATE) {
>> @@ -274,33 +278,37 @@ int sclp_service_call(CPUS390XState *env, uint64_t 
>> sccb, uint32_t code)
>>  return -PGM_SPECIFICATION;
>>  }
>>  
>> +/* the header contains the actual length of the sccb */
>> +cpu_physical_memory_read(sccb, , sizeof(SCCBHeader));
>> +
>> +/* Valid sccb sizes */
>> +if (be16_to_cpu(header.length) < sizeof(SCCBHeader)) {
>> +return -PGM_SPECIFICATION;
>> +}
>> +
>>  /*
>>   * we want to work on a private copy of the sccb, to preven

[PATCH v5 8/8] s390: guest support for diagnose 0x318

2020-09-10 Thread Collin Walling
DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
of diagnostic information that is collected by the firmware in the case
of hardware/firmware service events.

QEMU handles the instruction by storing the info in the CPU state. A
subsequent register sync will communicate the data to the hypervisor.

QEMU handles the migration via a VM State Description.

This feature depends on the Extended-Length SCCB (els) feature. If
els is not present, then a warning will be printed and the SCLP bit
that allows the Linux kernel to execute the instruction will not be
set.

Availability of this instruction is determined by byte 134 (aka fac134)
bit 0 of the SCLP Read Info block. This coincidentally expands into the
space used for CPU entries, which means VMs running with the diag318
capability may not be able to read information regarding all CPUs
unless the guest kernel supports an extended-length SCCB.

This feature is not supported in protected virtualization mode.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
---
 hw/s390x/sclp.c |  5 +
 include/hw/s390x/sclp.h |  3 +++
 target/s390x/cpu.h  |  2 ++
 target/s390x/cpu_features.h |  1 +
 target/s390x/cpu_features_def.h.inc |  3 +++
 target/s390x/cpu_models.c   |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  | 31 +
 target/s390x/machine.c  | 17 
 9 files changed, 64 insertions(+)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 87d468087b..ad5d70e14d 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -139,6 +139,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
  read_info->conf_char_ext);
 
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
+_info->fac134);
+}
+
 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 141e57f765..516f949109 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -133,6 +133,9 @@ typedef struct ReadInfo {
 uint16_t highest_cpu;
 uint8_t  _reserved5[124 - 122]; /* 122-123 */
 uint32_t hmfai;
+uint8_t  _reserved7[134 - 128]; /* 128-133 */
+uint8_t  fac134;
+uint8_t  _reserved8[144 - 135]; /* 135-143 */
 struct CPUEntry entries[];
 } QEMU_PACKED ReadInfo;
 
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 035427521c..f875ebf0f4 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -112,6 +112,8 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
+uint64_t diag318_info;
+
 /* Fields up to this point are cleared by a CPU reset */
 struct {} end_reset_fields;
 
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index 2a29475493..ef52ffce83 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_FAC134,
 S390_FEAT_TYPE_SCLP_CPU,
 S390_FEAT_TYPE_MISC,
 S390_FEAT_TYPE_PLO,
diff --git a/target/s390x/cpu_features_def.h.inc 
b/target/s390x/cpu_features_def.h.inc
index 1c04cc18f4..f82b4b5ec1 100644
--- a/target/s390x/cpu_features_def.h.inc
+++ b/target/s390x/cpu_features_def.h.inc
@@ -122,6 +122,9 @@ DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: 
Collaborative-memory-man
 DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation 
facility")
 DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: 
Interlock-and-broadcast-suppression facility")
 
+/* Features exposed via SCLP SCCB Facilities byte 134 (bit numbers relative to 
byte-134) */
+DEF_FEAT(DIAG_318, "diag318", SCLP_FAC134, 0, "Control program name and 
version codes")
+
 /* Features exposed via SCLP CPU info. */
 DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual 
SIE)")
 DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index c2af226174..9d615f13e7 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -824,6 +824,7 @@ static void check_consistency(const S390CPUModel *model)
 { S390_FEAT_PTFF_STOE, S390_FEAT_MULTIPLE_EPOCH },
 { S390_FEAT_PTFF_STOUE, S390_FEAT_MULTIPLE_EPOCH },
 { S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL, S390_FEAT_AP },
+{ S390_FEAT_DIAG_318, S390_FEAT_EXTENDED_LENGTH_SCCB },

[PATCH v5 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-09-10 Thread Collin Walling
As more features and facilities are added to the Read SCP Info (RSCPI)
response, more space is required to store them. The space used to store
these new features intrudes on the space originally used to store CPU
entries. This means as more features and facilities are added to the
RSCPI response, less space can be used to store CPU entries.

With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
the RSCPI command and determine if the SCCB is large enough to store a
complete reponse. If it is not large enough, then the required length
will be set in the SCCB header.

The caller of the SCLP command is responsible for creating a
large-enough SCCB to store a complete response. Proper checking should
be in place, and the caller should execute the command once-more with
the large-enough SCCB.

This facility also enables an extended SCCB for the Read CPU Info
(RCPUI) command.

When this facility is enabled, the boundary violation response cannot
be a result from the RSCPI, RSCPI Forced, or RCPUI commands.

In order to tolerate kernels that do not yet have full support for this
feature, a "fixed" offset to the start of the CPU Entries within the
Read SCP Info struct is set to allow for the original 248 max entries
when this feature is disabled.

Additionally, this is introduced as a CPU feature to protect the guest
from migrating to a machine that does not support storing an extended
SCCB. This could otherwise hinder the VM from being able to read all
available CPU entries after migration (such as during re-ipl).

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c | 43 +
 include/hw/s390x/sclp.h |  1 +
 target/s390x/cpu_features_def.h.inc |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  |  8 ++
 5 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 803fdd5ed4..87d468087b 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,13 +49,30 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t len)
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t len,
+ uint32_t code)
 {
 uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(len) - 1;
 uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
 
-if (sccb_max_addr < sccb_boundary) {
-return true;
+switch (code & SCLP_CMD_CODE_MASK) {
+case SCLP_CMDW_READ_SCP_INFO:
+case SCLP_CMDW_READ_SCP_INFO_FORCED:
+case SCLP_CMDW_READ_CPU_INFO:
+/*
+ * An extended-length SCCB is only allowed for Read SCP/CPU Info and
+ * is allowed to exceed the 4k boundary. The respective commands will
+ * set the length field to the required length if an insufficient
+ * SCCB length is provided.
+ */
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+return true;
+}
+/* fallthrough */
+default:
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
 }
 
 return false;
@@ -80,6 +97,12 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 
 #define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
 
+static inline bool ext_len_sccb_supported(SCCBHeader header)
+{
+return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
+   header.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE;
+}
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -89,10 +112,15 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
-int offset_cpu = offsetof(ReadInfo, entries);
+int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
+ offsetof(ReadInfo, entries) :
+ SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
 CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
+if (ext_len_sccb_supported(sccb->h)) {
+sccb->h.length = cpu_to_be16(required_len);
+}
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
 return;
 }
@@ -153,6 +181,9 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
+if (ext_len_sccb_supported(sccb->h)) {
+sccb->h.length = cpu_to_be16(required_len);
+}
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH

[PATCH v5 4/8] s390/sclp: check sccb len before filling in data

2020-09-10 Thread Collin Walling
The SCCB must be checked for a sufficient length before it is filled
with any data. If the length is insufficient, then the SCLP command
is suppressed and the proper response code is set in the SCCB header.

While we're at it, let's cleanup the length check by placing the
calculation inside a macro.

Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length")
Signed-off-by: Collin Walling 
Reviewed-by: Janosch Frank 
Reviewed-by: David Hildenbrand 
Reviewed-by: Cornelia Huck 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index cb8e2e8ec3..12829bdd05 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -78,6 +78,8 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 }
 }
 
+#define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry))
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -86,6 +88,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int cpu_count;
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
+int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
 
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
@@ -95,12 +103,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* Configuration Characteristic (Extension) */
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
  read_info->conf_char);
@@ -146,18 +148,18 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
+int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
 
 prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* The standby offset is 16-byte for each CPU */
 cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
 + cpu_info->nr_configured*sizeof(CPUEntry));
-- 
2.26.2




[PATCH v5 3/8] s390/sclp: read sccb from mem based on provided length

2020-09-10 Thread Collin Walling
The header contained within the SCCB passed to the SCLP service call
contains the actual length of the SCCB. Instead of allocating a static
4K size for the work sccb, let's allow for a variable size determined
by the value in the header. The proper checks are already in place to
ensure the SCCB length is sufficent to store a full response and that
the length does not cross any explicitly-set boundaries.

Signed-off-by: Collin Walling 
---
 hw/s390x/event-facility.c |  2 +-
 hw/s390x/sclp.c   | 58 ++-
 include/hw/s390x/sclp.h   |  2 +-
 3 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 645b4080c5..ed92ce510d 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -213,7 +213,7 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility 
*ef, SCCB *sccb,
 
 event_buf = >ebh;
 event_buf->length = 0;
-slen = sizeof(sccb->data);
+slen = sccb_data_len(sccb);
 
 rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
 
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 69a8724dc7..cb8e2e8ec3 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -231,25 +231,30 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 {
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
-SCCB work_sccb;
-hwaddr sccb_len = sizeof(SCCB);
+SCCBHeader header;
+SCCB *work_sccb;
 
-s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
+s390_cpu_pv_mem_read(env_archcpu(env), 0, , sizeof(SCCBHeader));
+
+work_sccb = g_malloc0(header.length);
+s390_cpu_pv_mem_read(env_archcpu(env), 0, work_sccb,
+ be16_to_cpu(header.length));
 
 if (!sclp_command_code_valid(code)) {
-work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 goto out_write;
 }
 
-if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
-work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+if (!sccb_verify_boundary(sccb, work_sccb->h.length)) {
+work_sccb->h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
 
-sclp_c->execute(sclp, _sccb, code);
+sclp_c->execute(sclp, work_sccb, code);
 out_write:
-s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
-  be16_to_cpu(work_sccb.h.length));
+s390_cpu_pv_mem_write(env_archcpu(env), 0, work_sccb,
+  be16_to_cpu(work_sccb->h.length));
+g_free(work_sccb);
 sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
 return 0;
 }
@@ -258,9 +263,8 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 {
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
-SCCB work_sccb;
-
-hwaddr sccb_len = sizeof(SCCB);
+SCCBHeader header;
+SCCB *work_sccb;
 
 /* first some basic checks on program checks */
 if (env->psw.mask & PSW_MASK_PSTATE) {
@@ -274,33 +278,37 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 return -PGM_SPECIFICATION;
 }
 
+/* the header contains the actual length of the sccb */
+cpu_physical_memory_read(sccb, , sizeof(SCCBHeader));
+
+/* Valid sccb sizes */
+if (be16_to_cpu(header.length) < sizeof(SCCBHeader)) {
+return -PGM_SPECIFICATION;
+}
+
 /*
  * we want to work on a private copy of the sccb, to prevent guests
  * from playing dirty tricks by modifying the memory content after
  * the host has checked the values
  */
-cpu_physical_memory_read(sccb, _sccb, sccb_len);
-
-/* Valid sccb sizes */
-if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
-return -PGM_SPECIFICATION;
-}
+work_sccb = g_malloc0(header.length);
+cpu_physical_memory_read(sccb, work_sccb, be16_to_cpu(header.length));
 
 if (!sclp_command_code_valid(code)) {
-work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+work_sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
 goto out_write;
 }
 
-if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
-work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+if (!sccb_verify_boundary(sccb, work_sccb->h.length)) {
+work_sccb->h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
 
-sclp_c->execute(sclp, _sccb, code);
+sclp_c->execute(sclp, work_sccb, code);
 out_write:
-cpu_physical_memory_write(sccb, _sccb,
-  be16_to_cpu(work_sccb.h.length));
-
+cpu_physical_memory_write(sccb, work_sccb,
+

[PATCH v5 7/8] s390/kvm: header sync for diag318

2020-09-10 Thread Collin Walling
Signed-off-by: Collin Walling 
---
 linux-headers/asm-s390/kvm.h | 7 +--
 linux-headers/linux/kvm.h| 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 0138ccb0d8..f053b8304a 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+#define KVM_SYNC_DIAG318 (1UL << 12)
 
 #define KVM_SYNC_S390_VALID_FIELDS \
(KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
 KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
-KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
+KVM_SYNC_DIAG318)
 
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
@@ -264,7 +266,8 @@ struct kvm_sync_regs {
__u8 reserved2 : 7;
__u8 padding1[51];  /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */
-   __u8 padding2[192]; /* sdnx needs to be 256byte aligned */
+   __u64 diag318;  /* diagnose 0x318 info */
+   __u8 padding2[184]; /* sdnx needs to be 256byte aligned */
union {
__u8 sdnx[SDNXL];  /* state description annex */
struct {
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index a28c366737..a789bfb5a2 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1031,6 +1031,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_SECURE_GUEST 181
 #define KVM_CAP_HALT_POLL 182
 #define KVM_CAP_ASYNC_PF_INT 183
+#define KVM_CAP_S390_DIAG318 184
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.26.2




[PATCH v5 1/8] s390/sclp: get machine once during read scp/cpu info

2020-09-10 Thread Collin Walling
Functions within read scp/cpu info will need access to the machine
state. Let's make a call to retrieve the machine state once and
pass the appropriate data to the respective functions.

Signed-off-by: Collin Walling 
Reviewed-by: David Hildenbrand 
Reviewed-by: Thomas Huth 
Reviewed-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index a0ce444b4b..28b973de8f 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,9 +49,8 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
+static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
 int i;
 
@@ -77,7 +76,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
 /* CPU information */
-prepare_cpu_entries(sclp, read_info->entries, _count);
+prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
@@ -132,10 +131,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 /* Provide information about the CPU */
 static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 {
+MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(sclp, cpu_info->entries, _count);
+prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
-- 
2.26.2




[PATCH v5 2/8] s390/sclp: rework sclp boundary checks

2020-09-10 Thread Collin Walling
Rework the SCLP boundary check to account for different SCLP commands
(eventually) allowing different boundary sizes.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 28b973de8f..69a8724dc7 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,6 +49,18 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint16_t len)
+{
+uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(len) - 1;
+uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
+
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
+
+return false;
+}
+
 static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
@@ -229,6 +241,11 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
+work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+goto out_write;
+}
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -274,7 +291,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
-if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + 
PAGE_SIZE)) {
+if (!sccb_verify_boundary(sccb, work_sccb.h.length)) {
 work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 goto out_write;
 }
-- 
2.26.2




[PATCH v5 5/8] s390/sclp: use cpu offset to locate cpu entries

2020-09-10 Thread Collin Walling
The start of the CPU entry region in the Read SCP Info response data is
denoted by the offset_cpu field. As such, QEMU needs to begin creating
entries at this address.

This is in preparation for when Read SCP Info inevitably introduces new
bytes that push the start of the CPUEntry field further away.

Read CPU Info is unlikely to ever change, so let's not bother
accounting for the offset there.

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 12829bdd05..803fdd5ed4 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -89,6 +89,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
+int offset_cpu = offsetof(ReadInfo, entries);
+CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
@@ -96,9 +98,9 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 }
 
 /* CPU information */
-prepare_cpu_entries(machine, read_info->entries, _count);
+prepare_cpu_entries(machine, entries_start, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
-read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
+read_info->offset_cpu = cpu_to_be16(offset_cpu);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
-- 
2.26.2




[PATCH v5 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-10 Thread Collin Walling
Janosch, Thomas, Conny: I've removed your r-b's from patch #3 since I
added some g_mallocs in place and I'd like to make sure things are
done properly there (explained in changelog, but let me know if further
explanation is necessary).

Janosch, please let me know if the changes to #3 are safe under PV.

Thanks.

Changelog:

v5

• removed sccb_verify_length function
- will simply use the length check code that was in place before

• introduced a macro for calculating required SCCB length
- takes a struct and max # of cpus as args

• work_sccb size is now dynamically allocated based on the length
  provided by the guest kernel, instead of always using a static
  4K size
- as such, the SCCB will have to be read twice:
- first time to retrieve the header
- second time with proper size after space for work_sccb 
  is allocated

v4

• added r-b's and ack's (thanks, everyone!)

• renamed boundary and length function

• updated header sync to reflect a change discussed in the respective
KVM patches

• s/data_len/offset_cpu

• added /* fallthrough */ comment in boundary check

v3

• Device IOCTLs removed
- diag 318 info is now communicated via sync_regs

• Reset code removed
- this is now handled in KVM
- diag318_info is stored within the CPU reset portion of the
S390CPUState

• Various cleanups for ELS preliminary patches

v2

• QEMU now handles the instruction call
- as such, the "enable diag 318" IOCTL has been removed

• patch #1 now changes the read scp/cpu info functions to
  retrieve the machine state once
- as such, I have not added any ack's or r-bs since this
  patch differs from the previous version

• patch #3 introduces a new "get_read_scp_info_data_len"
  function in order clean-up the variable data length assignment
  in patch #7
- a comment above this function should help clarify what's
  going on to make things a bit easier to read

• other misc clean ups and fixes
- s/diag318/diag_318 in order to keep the naming scheme
  consistent with Linux and other diag-related code
- s/byte_134/fac134 to align naming scheme with Linux

---

This patch series introduces two features for an s390 KVM quest:
- Extended-Length SCCB (els) for the Read SCP/CPU Info SCLP 
commands
- DIAGNOSE 0x318 (diag_318) enabling / migration handling

The diag 318 feature depends on els and KVM support.

The els feature is handled entirely with QEMU, and does not require 
KVM support.

Both features are made available starting with the zEC12-full model.

These patches are introduced together for two main reasons:
- els allows diag 318 to exist while retaining the original 248 
VCPU max
- diag 318 is presented to show how els is useful

Full els support is dependant on the Linux kernel, which must react
to the SCLP response code and set an appropriate-length SCCB. 

A user should take care when tuning the CPU model for a VM.
If a user defines a VM with els support and specifies 248 CPUs, but
the guest Linux kernel cannot react to the SCLP response code, then
the guest will crash immediately upon kernel startup.

Collin L. Walling (8):
  s390/sclp: get machine once during read scp/cpu info
  s390/sclp: rework sclp boundary checks
  s390/sclp: read sccb from mem based on provided length
  s390/sclp: check sccb len before filling in data
  s390/sclp: use cpu offset to locate cpu entries
  s390/sclp: add extended-length sccb support for kvm guest
  s390/kvm: header sync for diag318
  s390: guest support for diagnose 0x318

 hw/s390x/event-facility.c   |   2 +-
 hw/s390x/sclp.c | 145 
 include/hw/s390x/sclp.h |   6 +-
 linux-headers/asm-s390/kvm.h|   7 +-
 linux-headers/linux/kvm.h   |   1 +
 target/s390x/cpu.h  |   2 +
 target/s390x/cpu_features.h |   1 +
 target/s390x/cpu_features_def.h.inc |   4 +
 target/s390x/cpu_models.c   |   1 +
 target/s390x/gen-features.c |   2 +
 target/s390x/kvm.c  |  39 
 target/s390x/machine.c  |  17 
 12 files changed, 183 insertions(+), 44 deletions(-)

-- 
2.26.2




Re: [PATCH v4 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-10 Thread Collin Walling
On 9/10/20 2:38 AM, Cornelia Huck wrote:
> On Wed, 9 Sep 2020 14:13:55 -0400
> Collin Walling  wrote:
> 
>> Has this been merged yet? There is one patch that I neglected to include
>> in this series (I didn't realize it until now) that properly sets the
>> SCCB size in QEMU based on the length provided by the kernel (right now,
>> these patches allocate a static 4K size for the SCCB struct, which
>> causes a segfault).
>>
>> I can post my set with the fix as v5, or I can wait and post the fix as
>> a bandaid if the patches are already in.
>>
> 
> It's queued on s390-next right now, I can still update it.
> 
> Is that really an extra patch, or something that can be merged into the
> series? If the latter, I'd prefer a v5, if the former, I'd just queue
> that patch on top.
> 
> 

I'll post a v5. Thanks!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-09-09 Thread Collin Walling
On 9/9/20 5:43 AM, Cornelia Huck wrote:
> On Wed, 9 Sep 2020 10:46:23 +0200
> Cornelia Huck  wrote:
> 
>> On Wed, 9 Sep 2020 09:54:40 +0200
>> Christian Borntraeger  wrote:
>>
>>> On 16.07.20 14:02, Cornelia Huck wrote:  
>>>> On Wed, 15 Jul 2020 12:26:20 -0400
>>>> Collin Walling  wrote:
>>>> 
>>>>> On 7/15/20 12:04 PM, Cornelia Huck wrote:
>>>>>> On Wed, 15 Jul 2020 11:36:35 -0400
>>>>>> Collin Walling  wrote:
>>>>>>   
>>>>>>> Polite ping. Patches have been sitting on the list for a few weeks now,
>>>>>>> and it doesn't look like any further changes are requested (hopefully I
>>>>>>> didn't miss something).  
>>>>>>
>>>>>> The only thing I had was (I think) the logging of the length you just
>>>>>> replied to. We can still tweak things like that later, of course.
>>>>>>
>>>>>> As these patches depend on a headers sync, I could not yet queue them.
>>>>>> I can keep a preliminary version on a branch. I assume that the header
>>>>>> changes will go in during the next kernel merge window? (If I missed
>>>>>> something, apologies for that.)
>>>>>>   
>>>>>
>>>>> Gotcha. Thanks for the update :)
>>>>>
>>>>> There was an email on the KVM list a couple of days that made one change
>>>>> to the Linux header. Just changed the integer used for the DIAG cap,
>>>>> which should be reflected in QEMU as well.
>>>>>
>>>>> https://www.spinics.net/lists/kvm/msg220548.html
>>>>>
>>>>> Should I respin this patch series to include the new ack's and account
>>>>> for the header sync?
>>>>
>>>> No need for that, my tooling picks up acks and the headers update needs
>>>> to be replaced with a sync against a proper Linux version anyway.
>>>>
>>>> I've queued the patches on a local branch, and the only patch that did
>>>> not apply cleanly was the headers patch, which will get replaced later
>>>> anyway :) Just ping me when the kernel patches hit upstream, then I'll
>>>> do a header sync against the next -rc and queue the patches on
>>>> s390-next.
>>>
>>> What is the status of this patchset? The kernel part has been merged in 
>>> 5.9-rc1.
>>>   
>>
>> Thanks for letting me know, I'll go and process this now. (Had some
>> busy weeks + PTO.)
> 
> There were some minor conflicts, please double check that everything
> looks sane.
> 
> Thanks, applied.
> 
> 

Has this been merged yet? There is one patch that I neglected to include
in this series (I didn't realize it until now) that properly sets the
SCCB size in QEMU based on the length provided by the kernel (right now,
these patches allocate a static 4K size for the SCCB struct, which
causes a segfault).

I can post my set with the fix as v5, or I can wait and post the fix as
a bandaid if the patches are already in.

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 3/8] s390/sclp: rework sclp boundary and length checks

2020-07-24 Thread Collin Walling
On 7/23/20 2:26 AM, Cornelia Huck wrote:
> On Tue, 21 Jul 2020 14:40:14 -0400
> Collin Walling  wrote:
> 
>> On 7/21/20 4:41 AM, David Hildenbrand wrote:
> 
>>> The options I would support are
>>>
>>> 1. "sccb_boundary_is_valid" which returns "true" if valid
>>> 2. "sccb_boundary_is_invalid" which returns "true" if invalid
>>> 3. "sccb_boundary_validate" which returns "0" if valid and -EINVAL if not.
>>>
>>> Which makes reading this code a bit easier.
>>>   
> 
> Of these, I like option 1 best.
> 
>>
>> Sounds good. I'll takes this into consideration for the next round. (I
>> may wait just a little longer for that to allow more reviews to come in
>> from whoever has the time, if that's okay.)
> 
> We have to wait for (a) QEMU to do a release and (b) the Linux changes
> to merge upstream anyway, so we're not in a hurry :)
> 
> As said before, it already looked good from my side, but the suggested
> changes are fine with me as well.
> 
> 

Okay, thanks for the info.

I do want to send out a v5 of these patches. While working with someone
who is implementing the kernel support for the extended-length SCCB, we
found some snags. I'll highlight these changes/fixes in the respective
patches on the next version.

Thanks!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 3/8] s390/sclp: rework sclp boundary and length checks

2020-07-21 Thread Collin Walling
On 7/21/20 4:41 AM, David Hildenbrand wrote:
> [...]
> 
 +switch (code & SCLP_CMD_CODE_MASK) {
 +default:
 +if (sccb_max_addr < sccb_boundary) {
 +return true;
 +}
 +}
>>>
>>> ^ what is that?
>>>
>>> if ((code & SCLP_CMD_CODE_MASK) && sccb_max_addr < sccb_boundary) {
>>> return true;
>>> }
> 
> Oh, my tired eyes missed that it's actually only
> 
> if (sccb_max_addr < sccb_boundary) :)
> 
>>>
>>
>> I agree it looks pointless in this patch, but it makes more sense in
>> patch #6 where we introduce cases for the SCLP commands that bypass
>> these checks if the extended-length sccb feature is enabled.
> 
> I am really a friend of introducing stuff where needed. Just use a
> simple "if" here and convert to the switch in patch #6.
> 

I can understand that. This follows the whole "each patch should be
sufficient on its own" way of thinking. A switch with no cases and a
default _does_ look silly.

>>
 +header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
 +return false;
>>>
>>> So we return "false" on success? At least I consider that weird when
>>> returning the bool type. Maybe make it clearer what the function indicates
>>>
>>
>> Hmmm... I figured since there were more paths that can lead to success
>> (i.e. when I introduce the feat check in a later patch), then it made
>> more sense to to return false at the end. sclp_command_code_valid has
>> similar logic.
>>
>> But if boolean functions traditionally return true as the last return
>> value, I can rework it to align to coding preferences / standards.
>>
>>> "sccb_boundary_is_invalid"
>>>
>>
>> Unless it's simply the name that is confusing?
> 
> The options I would support are
> 
> 1. "sccb_boundary_is_valid" which returns "true" if valid
> 2. "sccb_boundary_is_invalid" which returns "true" if invalid
> 3. "sccb_boundary_validate" which returns "0" if valid and -EINVAL if not.
> 
> Which makes reading this code a bit easier.
> 

Sounds good. I'll takes this into consideration for the next round. (I
may wait just a little longer for that to allow more reviews to come in
from whoever has the time, if that's okay.)

>>
>>> or leave it named as is and switch from return value "bool" to "int",
>>> using "0" on success and "-EINVAL" on error.
>>>
>>
>> Is the switch statement an overkill? I thought of it as a cleaner way to
>> later show which commands have a special conditions (introduced in patch
>> 6 for the ELS stuff) instead of a nasty long if statement.
> 
> I think the switch make sense in patch #6.
> 


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 3/8] s390/sclp: rework sclp boundary and length checks

2020-07-20 Thread Collin Walling
On 7/20/20 4:17 AM, David Hildenbrand wrote:
> On 24.06.20 22:23, Collin Walling wrote:
>> Rework the SCLP boundary check to account for different SCLP commands
>> (eventually) allowing different boundary sizes.
>>
>> Move the length check code into a separate function, and introduce a
>> new function to determine the length of the read SCP data (i.e. the size
>> from the start of the struct to where the CPU entries should begin).
>>
>> The format of read CPU info is unlikely to change in the future,
>> so we do not require a separate function to calculate its length.
>>
>> Signed-off-by: Collin Walling 
>> Acked-by: Janosch Frank 
>> Reviewed-by: Cornelia Huck 
>> ---
>>  hw/s390x/sclp.c | 54 -
>>  1 file changed, 44 insertions(+), 10 deletions(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 181ce04007..5899c1e3b8 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -49,6 +49,34 @@ static inline bool sclp_command_code_valid(uint32_t code)
>>  return false;
>>  }
>>  
>> +static bool sccb_verify_boundary(uint64_t sccb_addr, uint32_t code,
>> + SCCBHeader *header)
>> +{
>> +uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(header->length) - 1;
>> +uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>> +
>> +switch (code & SCLP_CMD_CODE_MASK) {
>> +default:
>> +if (sccb_max_addr < sccb_boundary) {
>> +return true;
>> +}
>> +}
> 
> ^ what is that?
> 
> if ((code & SCLP_CMD_CODE_MASK) && sccb_max_addr < sccb_boundary) {
> return true;
> }
> 

I agree it looks pointless in this patch, but it makes more sense in
patch #6 where we introduce cases for the SCLP commands that bypass
these checks if the extended-length sccb feature is enabled.

>> +header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>> +return false;
> 
> So we return "false" on success? At least I consider that weird when
> returning the bool type. Maybe make it clearer what the function indicates
> 

Hmmm... I figured since there were more paths that can lead to success
(i.e. when I introduce the feat check in a later patch), then it made
more sense to to return false at the end. sclp_command_code_valid has
similar logic.

But if boolean functions traditionally return true as the last return
value, I can rework it to align to coding preferences / standards.

> "sccb_boundary_is_invalid"
> 

Unless it's simply the name that is confusing?

> or leave it named as is and switch from return value "bool" to "int",
> using "0" on success and "-EINVAL" on error.
> 

Is the switch statement an overkill? I thought of it as a cleaner way to
later show which commands have a special conditions (introduced in patch
6 for the ELS stuff) instead of a nasty long if statement.

The alternative...

/* Comment explaining this check */
if ((code & SCLP_CMD_CODE_MASK) & (SCLP_CMDW_READ_SCP_INFO |
SCLP_CMDW_READ_SCP_INFO_FORCED | SCLP_CMDW_READ_CPU_INFO) &&
s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
return true;
}

if (sccb_max_addr < sccb_boundary) {
return true;
}

header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
return false;

[...]

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 4/8] s390/sclp: read sccb from mem based on sccb length

2020-07-20 Thread Collin Walling
On 7/20/20 4:19 AM, David Hildenbrand wrote:
> On 24.06.20 22:23, Collin Walling wrote:
>> The header of the SCCB contains the actual length of the SCCB. Instead
>> of using a static 4K size, let's allow for a variable size determined
>> by the value set in the header. The proper checks are already in place
>> to ensure the SCCB length is sufficent to store a full response, and
>> that the length does not cross any explicitly-set boundaries.
>>
>> Signed-off-by: Collin Walling 
>> Reviewed-by: Thomas Huth 
>> Reviewed-by: Janosch Frank 
>> Reviewed-by: Cornelia Huck 
>> ---
>>  hw/s390x/sclp.c | 13 -
>>  1 file changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 5899c1e3b8..1feba6f692 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -251,9 +251,8 @@ int sclp_service_call_protected(CPUS390XState *env, 
>> uint64_t sccb,
>>  SCLPDevice *sclp = get_sclp_device();
>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>>  SCCB work_sccb;
>> -hwaddr sccb_len = sizeof(SCCB);
>>  
>> -s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, 
>> sizeof(SCCBHeader));
>>  
>>  if (!sclp_command_code_valid(code)) {
>>  work_sccb.h.response_code = 
>> cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
>> @@ -264,6 +263,9 @@ int sclp_service_call_protected(CPUS390XState *env, 
>> uint64_t sccb,
>>  goto out_write;
>>  }
>>  
>> +s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb,
>> + be16_to_cpu(work_sccb.h.length));
>> +
>>  sclp_c->execute(sclp, _sccb, code);
>>  out_write:
>>  s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
>> @@ -278,8 +280,6 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
>> uint32_t code)
>>  SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
>>  SCCB work_sccb;
>>  
>> -hwaddr sccb_len = sizeof(SCCB);
>> -
>>  /* first some basic checks on program checks */
>>  if (env->psw.mask & PSW_MASK_PSTATE) {
>>  return -PGM_PRIVILEGED;
>> @@ -297,7 +297,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
>> uint32_t code)
>>   * from playing dirty tricks by modifying the memory content after
>>   * the host has checked the values
>>   */
>> -cpu_physical_memory_read(sccb, _sccb, sccb_len);
>> +cpu_physical_memory_read(sccb, _sccb, sizeof(SCCBHeader));
>>  
>>  /* Valid sccb sizes */
>>  if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
>> @@ -313,6 +313,9 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
>> uint32_t code)
>>  goto out_write;
>>  }
>>  
>> +/* the header contains the actual length of the sccb */
>> +cpu_physical_memory_read(sccb, _sccb, 
>> be16_to_cpu(work_sccb.h.length));
>> +
>>  sclp_c->execute(sclp, _sccb, code);
>>  out_write:
>>  cpu_physical_memory_write(sccb, _sccb,
>>
> 
> Reviewed-by: David Hildenbrand 
> 

Thanks!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-07-15 Thread Collin Walling
On 7/15/20 12:04 PM, Cornelia Huck wrote:
> On Wed, 15 Jul 2020 11:36:35 -0400
> Collin Walling  wrote:
> 
>> Polite ping. Patches have been sitting on the list for a few weeks now,
>> and it doesn't look like any further changes are requested (hopefully I
>> didn't miss something).
> 
> The only thing I had was (I think) the logging of the length you just
> replied to. We can still tweak things like that later, of course.
> 
> As these patches depend on a headers sync, I could not yet queue them.
> I can keep a preliminary version on a branch. I assume that the header
> changes will go in during the next kernel merge window? (If I missed
> something, apologies for that.)
> 

Gotcha. Thanks for the update :)

There was an email on the KVM list a couple of days that made one change
to the Linux header. Just changed the integer used for the DIAG cap,
which should be reflected in QEMU as well.

https://www.spinics.net/lists/kvm/msg220548.html

Should I respin this patch series to include the new ack's and account
for the header sync?

>>
>> Thanks for everyone's time and patience. Stay safe out there.
>>
>>  - Collin
>>
> 
> 


-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v4 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-07-15 Thread Collin Walling
Polite ping. Patches have been sitting on the list for a few weeks now,
and it doesn't look like any further changes are requested (hopefully I
didn't miss something).

Thanks for everyone's time and patience. Stay safe out there.

 - Collin



Re: [PATCH v4 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-07-15 Thread Collin Walling
On 6/26/20 6:01 AM, Cornelia Huck wrote:
> On Wed, 24 Jun 2020 16:23:10 -0400
> Collin Walling  wrote:
> 
>> As more features and facilities are added to the Read SCP Info (RSCPI)
>> response, more space is required to store them. The space used to store
>> these new features intrudes on the space originally used to store CPU
>> entries. This means as more features and facilities are added to the
>> RSCPI response, less space can be used to store CPU entries.
>>
>> With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
>> the RSCPI command and determine if the SCCB is large enough to store a
>> complete reponse. If it is not large enough, then the required length
>> will be set in the SCCB header.
>>
>> The caller of the SCLP command is responsible for creating a
>> large-enough SCCB to store a complete response. Proper checking should
>> be in place, and the caller should execute the command once-more with
>> the large-enough SCCB.
>>
>> This facility also enables an extended SCCB for the Read CPU Info
>> (RCPUI) command.
>>
>> When this facility is enabled, the boundary violation response cannot
>> be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
>>
>> In order to tolerate kernels that do not yet have full support for this
>> feature, a "fixed" offset to the start of the CPU Entries within the
>> Read SCP Info struct is set to allow for the original 248 max entries
>> when this feature is disabled.
>>
>> Additionally, this is introduced as a CPU feature to protect the guest
>> from migrating to a machine that does not support storing an extended
>> SCCB. This could otherwise hinder the VM from being able to read all
>> available CPU entries after migration (such as during re-ipl).
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  hw/s390x/sclp.c | 24 +++-
>>  include/hw/s390x/sclp.h |  1 +
>>  target/s390x/cpu_features_def.inc.h |  1 +
>>  target/s390x/gen-features.c |  1 +
>>  target/s390x/kvm.c  |  8 
>>  5 files changed, 34 insertions(+), 1 deletion(-)
>>
> 
> (...)
> 
>> @@ -111,6 +131,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  CPUEntry *entries_start = (void *)sccb + offset_cpu;
>>  
>>  if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) 
>> {
>> +qemu_log_mask(LOG_GUEST_ERROR, "insufficient sccb size to store "
>> +  "read scp info response\n");
> 
> Not sure if logging needed/provided length would be helpful here.
> 

I had the thought that it may be beneficial for kernel development -- it
gives a response if an SCCB size needs to be larger.

>>  return;
>>  }
>>  
> 
> (...)
> 
> Acked-by: Cornelia Huck 
> 

Thanks.

-- 
Regards,
Collin

Stay safe and stay healthy



[PATCH v4 3/8] s390/sclp: rework sclp boundary and length checks

2020-06-24 Thread Collin Walling
Rework the SCLP boundary check to account for different SCLP commands
(eventually) allowing different boundary sizes.

Move the length check code into a separate function, and introduce a
new function to determine the length of the read SCP data (i.e. the size
from the start of the struct to where the CPU entries should begin).

The format of read CPU info is unlikely to change in the future,
so we do not require a separate function to calculate its length.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 54 -
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 181ce04007..5899c1e3b8 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,6 +49,34 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
+static bool sccb_verify_boundary(uint64_t sccb_addr, uint32_t code,
+ SCCBHeader *header)
+{
+uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(header->length) - 1;
+uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
+
+switch (code & SCLP_CMD_CODE_MASK) {
+default:
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
+}
+header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+return false;
+}
+
+/* Calculates sufficient SCCB length to store a full Read SCP/CPU response */
+static bool sccb_verify_length(SCCB *sccb, int num_cpus, int offset_cpu)
+{
+int required_len = offset_cpu + num_cpus * sizeof(CPUEntry);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return false;
+}
+return true;
+}
+
 static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
@@ -66,6 +94,11 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 }
 }
 
+static inline int get_read_scp_info_offset_cpu(void)
+{
+return offsetof(ReadInfo, entries);
+}
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -74,17 +107,16 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int cpu_count;
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
+int offset_cpu = get_read_scp_info_offset_cpu();
 
-if (be16_to_cpu(sccb->h.length) <
-  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) {
 return;
 }
 
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
-read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
+read_info->offset_cpu = cpu_to_be16(offset_cpu);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
@@ -133,17 +165,16 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
+int offset_cpu = offsetof(ReadCpuInfo, entries);
 int cpu_count;
 
-if (be16_to_cpu(sccb->h.length) <
-  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) {
 return;
 }
 
 prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
-cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
+cpu_info->offset_configured = cpu_to_be16(offset_cpu);
 cpu_info->nr_standby = cpu_to_be16(0);
 
 /* The standby offset is 16-byte for each CPU */
@@ -229,6 +260,10 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+if (!sccb_verify_boundary(sccb, code, _sccb.h)) {
+goto out_write;
+}
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -274,8 +309,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
-if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + 
PAGE_SIZE)) {
-work_sccb.h.response_code = 
cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+if (!sccb_verify_boundary(sccb, code, _sccb.h)) {
 goto out_write;
 }
 
-- 
2.26.2




[PATCH v4 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-06-24 Thread Collin Walling
Changelog:

v4

• added r-b's and ack's (thanks, everyone!)

• renamed boundary and length function

• updated header sync to reflect a change discussed in the respective
KVM patches

• s/data_len/offset_cpu

• added /* fallthrough */ comment in boundary check

v3

• Device IOCTLs removed
- diag 318 info is now communicated via sync_regs

• Reset code removed
- this is now handled in KVM
- diag318_info is stored within the CPU reset portion of the
S390CPUState

• Various cleanups for ELS preliminary patches

v2

• QEMU now handles the instruction call
- as such, the "enable diag 318" IOCTL has been removed

• patch #1 now changes the read scp/cpu info functions to
  retrieve the machine state once
- as such, I have not added any ack's or r-bs since this
  patch differs from the previous version

• patch #3 introduces a new "get_read_scp_info_data_len"
  function in order clean-up the variable data length assignment
  in patch #7
- a comment above this function should help clarify what's
  going on to make things a bit easier to read

• other misc clean ups and fixes
- s/diag318/diag_318 in order to keep the naming scheme
  consistent with Linux and other diag-related code
- s/byte_134/fac134 to align naming scheme with Linux

---

This patch series introduces two features for an s390 KVM quest:
- Extended-Length SCCB (els) for the Read SCP/CPU Info SCLP 
commands
- DIAGNOSE 0x318 (diag_318) enabling / migration handling

The diag 318 feature depends on els and KVM support.

The els feature is handled entirely with QEMU, and does not require 
KVM support.

Both features are made available starting with the zEC12-full model.

These patches are introduced together for two main reasons:
- els allows diag 318 to exist while retaining the original 248 
VCPU max
- diag 318 is presented to show how els is useful

Full els support is dependant on the Linux kernel, which must react
to the SCLP response code and set an appropriate-length SCCB. 

A user should take care when tuning the CPU model for a VM.
If a user defines a VM with els support and specifies 248 CPUs, but
the guest Linux kernel cannot react to the SCLP response code, then
the guest will crash immediately upon kernel startup.


Collin L. Walling (8):
  s390/sclp: get machine once during read scp/cpu info
  s390/sclp: check sccb len before filling in data
  s390/sclp: rework sclp boundary and length checks
  s390/sclp: read sccb from mem based on sccb length
  s390/sclp: use cpu offset to locate cpu entries
  s390/sclp: add extended-length sccb support for kvm guest
  s390/kvm: header sync for diag318
  s390: guest support for diagnose 0x318

 hw/s390x/sclp.c | 115 ++--
 include/hw/s390x/sclp.h |   4 +
 linux-headers/asm-s390/kvm.h|   7 +-
 linux-headers/linux/kvm.h   |   1 +
 target/s390x/cpu.h  |   2 +
 target/s390x/cpu_features.h |   1 +
 target/s390x/cpu_features_def.inc.h |   4 +
 target/s390x/cpu_models.c   |   1 +
 target/s390x/gen-features.c |   2 +
 target/s390x/kvm.c  |  39 ++
 target/s390x/machine.c  |  17 
 11 files changed, 166 insertions(+), 27 deletions(-)

-- 
2.26.2




[PATCH v4 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-06-24 Thread Collin Walling
As more features and facilities are added to the Read SCP Info (RSCPI)
response, more space is required to store them. The space used to store
these new features intrudes on the space originally used to store CPU
entries. This means as more features and facilities are added to the
RSCPI response, less space can be used to store CPU entries.

With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
the RSCPI command and determine if the SCCB is large enough to store a
complete reponse. If it is not large enough, then the required length
will be set in the SCCB header.

The caller of the SCLP command is responsible for creating a
large-enough SCCB to store a complete response. Proper checking should
be in place, and the caller should execute the command once-more with
the large-enough SCCB.

This facility also enables an extended SCCB for the Read CPU Info
(RCPUI) command.

When this facility is enabled, the boundary violation response cannot
be a result from the RSCPI, RSCPI Forced, or RCPUI commands.

In order to tolerate kernels that do not yet have full support for this
feature, a "fixed" offset to the start of the CPU Entries within the
Read SCP Info struct is set to allow for the original 248 max entries
when this feature is disabled.

Additionally, this is introduced as a CPU feature to protect the guest
from migrating to a machine that does not support storing an extended
SCCB. This could otherwise hinder the VM from being able to read all
available CPU entries after migration (such as during re-ipl).

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c | 24 +++-
 include/hw/s390x/sclp.h |  1 +
 target/s390x/cpu_features_def.inc.h |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  |  8 
 5 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 518f630938..2e83b4f598 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -22,6 +22,7 @@
 #include "hw/s390x/event-facility.h"
 #include "hw/s390x/s390-pci-bus.h"
 #include "hw/s390x/ipl.h"
+#include "qemu/log.h"
 
 static inline SCLPDevice *get_sclp_device(void)
 {
@@ -56,6 +57,19 @@ static bool sccb_verify_boundary(uint64_t sccb_addr, 
uint32_t code,
 uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
 
 switch (code & SCLP_CMD_CODE_MASK) {
+case SCLP_CMDW_READ_SCP_INFO:
+case SCLP_CMDW_READ_SCP_INFO_FORCED:
+case SCLP_CMDW_READ_CPU_INFO:
+/*
+ * An extended-length SCCB is only allowed for Read SCP/CPU Info and
+ * is allowed to exceed the 4k boundary. The respective commands will
+ * set the length field to the required length if an insufficient
+ * SCCB length is provided.
+ */
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+return true;
+}
+/* fallthrough */
 default:
 if (sccb_max_addr < sccb_boundary) {
 return true;
@@ -72,6 +86,10 @@ static bool sccb_verify_length(SCCB *sccb, int num_cpus, int 
offset_cpu)
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
+sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) {
+sccb->h.length = required_len;
+}
 return false;
 }
 return true;
@@ -96,7 +114,9 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 
 static inline int get_read_scp_info_offset_cpu(void)
 {
-return offsetof(ReadInfo, entries);
+return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
+   offsetof(ReadInfo, entries) :
+   SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
 }
 
 /* Provide information about the configuration, CPUs and storage */
@@ -111,6 +131,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) {
+qemu_log_mask(LOG_GUEST_ERROR, "insufficient sccb size to store "
+  "read scp info response\n");
 return;
 }
 
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 822eff4396..ef2d63eae9 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -110,6 +110,7 @@ typedef struct CPUEntry {
 uint8_t reserved1;
 } QEMU_PACKED CPUEntry;
 
+#define SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET 128
 typedef struct ReadInfo {
 SCCBHeader h;
 uint16_t rnmax;
diff --git a/target/s390x/cpu_features_def.inc.h 
b/target/s390x/cpu_features_def.inc.h
index 5942f81f16..1c04cc18f4 100644
--- a/target/s390x/cpu_features_def.inc.h
+++ b/target/s390x/cpu_features_def.inc.h
@@ -97,6 +97,7

[PATCH v4 1/8] s390/sclp: get machine once during read scp/cpu info

2020-06-24 Thread Collin Walling
Functions within read scp/cpu info will need access to the machine
state. Let's make a call to retrieve the machine state once and
pass the appropriate data to the respective functions.

Signed-off-by: Collin Walling 
Reviewed-by: David Hildenbrand 
Reviewed-by: Thomas Huth 
Reviewed-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 20aca30ac4..7875334037 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,9 +49,8 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
+static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
 int i;
 
@@ -77,7 +76,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
 /* CPU information */
-prepare_cpu_entries(sclp, read_info->entries, _count);
+prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
@@ -132,10 +131,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 /* Provide information about the CPU */
 static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 {
+MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(sclp, cpu_info->entries, _count);
+prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
-- 
2.26.2




[PATCH v4 2/8] s390/sclp: check sccb len before filling in data

2020-06-24 Thread Collin Walling
The SCCB must be checked for a sufficient length before it is filled
with any data. If the length is insufficient, then the SCLP command
is suppressed and the proper response code is set in the SCCB header.

Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length")
Signed-off-by: Collin Walling 
Reviewed-by: Janosch Frank 
Reviewed-by: David Hildenbrand 
Reviewed-by: Cornelia Huck 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 7875334037..181ce04007 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -75,6 +75,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
+if (be16_to_cpu(sccb->h.length) <
+  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
+
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
@@ -83,12 +89,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* Configuration Characteristic (Extension) */
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
  read_info->conf_char);
@@ -135,17 +135,17 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(machine, cpu_info->entries, _count);
-cpu_info->nr_configured = cpu_to_be16(cpu_count);
-cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
-cpu_info->nr_standby = cpu_to_be16(0);
-
 if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
+  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
 return;
 }
 
+prepare_cpu_entries(machine, cpu_info->entries, _count);
+cpu_info->nr_configured = cpu_to_be16(cpu_count);
+cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
+cpu_info->nr_standby = cpu_to_be16(0);
+
 /* The standby offset is 16-byte for each CPU */
 cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
 + cpu_info->nr_configured*sizeof(CPUEntry));
-- 
2.26.2




[PATCH v4 4/8] s390/sclp: read sccb from mem based on sccb length

2020-06-24 Thread Collin Walling
The header of the SCCB contains the actual length of the SCCB. Instead
of using a static 4K size, let's allow for a variable size determined
by the value set in the header. The proper checks are already in place
to ensure the SCCB length is sufficent to store a full response, and
that the length does not cross any explicitly-set boundaries.

Signed-off-by: Collin Walling 
Reviewed-by: Thomas Huth 
Reviewed-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 5899c1e3b8..1feba6f692 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -251,9 +251,8 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 SCCB work_sccb;
-hwaddr sccb_len = sizeof(SCCB);
 
-s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
+s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sizeof(SCCBHeader));
 
 if (!sclp_command_code_valid(code)) {
 work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
@@ -264,6 +263,9 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb,
+ be16_to_cpu(work_sccb.h.length));
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -278,8 +280,6 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 SCCB work_sccb;
 
-hwaddr sccb_len = sizeof(SCCB);
-
 /* first some basic checks on program checks */
 if (env->psw.mask & PSW_MASK_PSTATE) {
 return -PGM_PRIVILEGED;
@@ -297,7 +297,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
  * from playing dirty tricks by modifying the memory content after
  * the host has checked the values
  */
-cpu_physical_memory_read(sccb, _sccb, sccb_len);
+cpu_physical_memory_read(sccb, _sccb, sizeof(SCCBHeader));
 
 /* Valid sccb sizes */
 if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
@@ -313,6 +313,9 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
+/* the header contains the actual length of the sccb */
+cpu_physical_memory_read(sccb, _sccb, 
be16_to_cpu(work_sccb.h.length));
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 cpu_physical_memory_write(sccb, _sccb,
-- 
2.26.2




[PATCH v4 8/8] s390: guest support for diagnose 0x318

2020-06-24 Thread Collin Walling
DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
of diagnostic information that is collected by the firmware in the case
of hardware/firmware service events.

QEMU handles the instruction by storing the info in the CPU state. A
subsequent register sync will communicate the data to the hypervisor.

QEMU handles the migration via a VM State Description.

This feature depends on the Extended-Length SCCB (els) feature. If
els is not present, then a warning will be printed and the SCLP bit
that allows the Linux kernel to execute the instruction will not be
set.

Availability of this instruction is determined by byte 134 (aka fac134)
bit 0 of the SCLP Read Info block. This coincidentally expands into the
space used for CPU entries, which means VMs running with the diag318
capability may not be able to read information regarding all CPUs
unless the guest kernel supports an extended-length SCCB.

This feature is not supported in protected virtualization mode.

Signed-off-by: Collin Walling 
Acked-by: Janosch Frank 
---
 hw/s390x/sclp.c |  5 +
 include/hw/s390x/sclp.h |  3 +++
 target/s390x/cpu.h  |  2 ++
 target/s390x/cpu_features.h |  1 +
 target/s390x/cpu_features_def.inc.h |  3 +++
 target/s390x/cpu_models.c   |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  | 31 +
 target/s390x/machine.c  | 17 
 9 files changed, 64 insertions(+)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 2e83b4f598..03068d7380 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -150,6 +150,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
  read_info->conf_char_ext);
 
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
+_info->fac134);
+}
+
 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 ef2d63eae9..ccb9f0a676 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -133,6 +133,9 @@ typedef struct ReadInfo {
 uint16_t highest_cpu;
 uint8_t  _reserved5[124 - 122]; /* 122-123 */
 uint32_t hmfai;
+uint8_t  _reserved7[134 - 128]; /* 128-133 */
+uint8_t  fac134;
+uint8_t  _reserved8[144 - 135]; /* 135-143 */
 struct CPUEntry entries[];
 } QEMU_PACKED ReadInfo;
 
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 035427521c..f875ebf0f4 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -112,6 +112,8 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
+uint64_t diag318_info;
+
 /* Fields up to this point are cleared by a CPU reset */
 struct {} end_reset_fields;
 
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index da695a8346..f74f7fc3a1 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_FAC134,
 S390_FEAT_TYPE_SCLP_CPU,
 S390_FEAT_TYPE_MISC,
 S390_FEAT_TYPE_PLO,
diff --git a/target/s390x/cpu_features_def.inc.h 
b/target/s390x/cpu_features_def.inc.h
index 1c04cc18f4..f82b4b5ec1 100644
--- a/target/s390x/cpu_features_def.inc.h
+++ b/target/s390x/cpu_features_def.inc.h
@@ -122,6 +122,9 @@ DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: 
Collaborative-memory-man
 DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation 
facility")
 DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: 
Interlock-and-broadcast-suppression facility")
 
+/* Features exposed via SCLP SCCB Facilities byte 134 (bit numbers relative to 
byte-134) */
+DEF_FEAT(DIAG_318, "diag318", SCLP_FAC134, 0, "Control program name and 
version codes")
+
 /* Features exposed via SCLP CPU info. */
 DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual 
SIE)")
 DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 2fa609bffe..034673be54 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -827,6 +827,7 @@ static void check_consistency(const S390CPUModel *model)
 { S390_FEAT_PTFF_STOE, S390_FEAT_MULTIPLE_EPOCH },
 { S390_FEAT_PTFF_STOUE, S390_FEAT_MULTIPLE_EPOCH },
 { S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL, S390_FEAT_AP },
+{ S390_FEAT_DIAG_318, S390_FEAT_EXTENDED_LENGTH_SCCB },

[PATCH v4 5/8] s390/sclp: use cpu offset to locate cpu entries

2020-06-24 Thread Collin Walling
The start of the CPU entry region in the Read SCP Info response data is
denoted by the offset_cpu field. As such, QEMU needs to begin creating
entries at this address. Note that the length of the Read SCP Info data
(data_len) denotes the same value as the cpu offset.

This is in preparation of when Read SCP Info inevitably introduces new
bytes that push the start of the CPUEntry field further away.

Read CPU Info is unlikely to ever change, so let's not bother
accounting for the offset there.

Signed-off-by: Collin Walling 
Reviewed-by: Thomas Huth 
Reviewed-by: Janosch Frank 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/sclp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 1feba6f692..518f630938 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -108,13 +108,14 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int offset_cpu = get_read_scp_info_offset_cpu();
+CPUEntry *entries_start = (void *)sccb + offset_cpu;
 
 if (!sccb_verify_length(sccb, machine->possible_cpus->len, offset_cpu)) {
 return;
 }
 
 /* CPU information */
-prepare_cpu_entries(machine, read_info->entries, _count);
+prepare_cpu_entries(machine, entries_start, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(offset_cpu);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
-- 
2.26.2




[PATCH v4 7/8] s390/kvm: header sync for diag318

2020-06-24 Thread Collin Walling
Signed-off-by: Collin Walling 
---
 linux-headers/asm-s390/kvm.h | 7 +--
 linux-headers/linux/kvm.h| 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 0138ccb0d8..f053b8304a 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+#define KVM_SYNC_DIAG318 (1UL << 12)
 
 #define KVM_SYNC_S390_VALID_FIELDS \
(KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
 KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
-KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
+KVM_SYNC_DIAG318)
 
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
@@ -264,7 +266,8 @@ struct kvm_sync_regs {
__u8 reserved2 : 7;
__u8 padding1[51];  /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */
-   __u8 padding2[192]; /* sdnx needs to be 256byte aligned */
+   __u64 diag318;  /* diagnose 0x318 info */
+   __u8 padding2[184]; /* sdnx needs to be 256byte aligned */
union {
__u8 sdnx[SDNXL];  /* state description annex */
struct {
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 9804495a46..444fdd977f 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1017,6 +1017,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_VCPU_RESETS 179
 #define KVM_CAP_S390_PROTECTED 180
 #define KVM_CAP_PPC_SECURE_GUEST 181
+#define KVM_CAP_S390_DIAG318 184
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.26.2




Re: [PATCH v3 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-06-24 Thread Collin Walling
On 6/24/20 8:55 AM, Cornelia Huck wrote:
> On Wed, 24 Jun 2020 14:40:58 +0200
> Thomas Huth  wrote:
> 
>> On 24/06/2020 14.36, Cornelia Huck wrote:
>>> On Thu, 18 Jun 2020 18:22:56 -0400
>>> Collin Walling  wrote:
>>>   
>>>> As more features and facilities are added to the Read SCP Info (RSCPI)
>>>> response, more space is required to store them. The space used to store
>>>> these new features intrudes on the space originally used to store CPU
>>>> entries. This means as more features and facilities are added to the
>>>> RSCPI response, less space can be used to store CPU entries.
>>>>
>>>> With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
>>>> the RSCPI command and determine if the SCCB is large enough to store a
>>>> complete reponse. If it is not large enough, then the required length
>>>> will be set in the SCCB header.
>>>>
>>>> The caller of the SCLP command is responsible for creating a
>>>> large-enough SCCB to store a complete response. Proper checking should
>>>> be in place, and the caller should execute the command once-more with
>>>> the large-enough SCCB.
>>>>
>>>> This facility also enables an extended SCCB for the Read CPU Info
>>>> (RCPUI) command.
>>>>
>>>> When this facility is enabled, the boundary violation response cannot
>>>> be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
>>>>
>>>> In order to tolerate kernels that do not yet have full support for this
>>>> feature, a "fixed" offset to the start of the CPU Entries within the
>>>> Read SCP Info struct is set to allow for the original 248 max entries
>>>> when this feature is disabled.
>>>>
>>>> Additionally, this is introduced as a CPU feature to protect the guest
>>>> from migrating to a machine that does not support storing an extended
>>>> SCCB. This could otherwise hinder the VM from being able to read all
>>>> available CPU entries after migration (such as during re-ipl).
>>>>
>>>> Signed-off-by: Collin Walling 
>>>> ---
>>>>   hw/s390x/sclp.c | 21 -
>>>>   include/hw/s390x/sclp.h |  1 +
>>>>   target/s390x/cpu_features_def.inc.h |  1 +
>>>>   target/s390x/gen-features.c |  1 +
>>>>   target/s390x/kvm.c  |  8 
>>>>   5 files changed, 31 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>>>> index 0dfbe6e5ec..f7c49e339e 100644
>>>> --- a/hw/s390x/sclp.c
>>>> +++ b/hw/s390x/sclp.c
>>>> @@ -56,6 +56,18 @@ static bool sccb_has_valid_boundary(uint64_t sccb_addr, 
>>>> uint32_t code,
>>>>   uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>>>>   
>>>>   switch (code & SCLP_CMD_CODE_MASK) {
>>>> +case SCLP_CMDW_READ_SCP_INFO:
>>>> +case SCLP_CMDW_READ_SCP_INFO_FORCED:
>>>> +case SCLP_CMDW_READ_CPU_INFO:
>>>> +/*
>>>> + * An extended-length SCCB is only allowed for Read SCP/CPU Info 
>>>> and
>>>> + * is allowed to exceed the 4k boundary. The respective commands 
>>>> will
>>>> + * set the length field to the required length if an insufficient
>>>> + * SCCB length is provided.
>>>> + */
>>>> +if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
>>>> +return true;
>>>> +}  
>>>
>>> Add a fallthrough annotation?  
>>
>> ... otherwise Coverity and friends will complain later.
> 
> Nod.
> 

Something simple like...

/* without this feature, these commands must respect the 4k boundary */

?

>>
>>>>   default:
>>>>   if (sccb_max_addr < sccb_boundary) {
>>>>   return true;
>>>> @@ -72,6 +84,10 @@ static bool sccb_sufficient_len(SCCB *sccb, int 
>>>> num_cpus, int data_len)
>>>>   
>>>>   if (be16_to_cpu(sccb->h.length) < required_len) {
>>>>   sccb->h.response_code = 
>>>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>>>> +if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
>>>> +sccb->h.control_mask[2] & SCLP_V

Re: [PATCH v3 3/8] s390/sclp: rework sclp boundary and length checks

2020-06-22 Thread Collin Walling
On 6/22/20 11:22 AM, Christian Borntraeger wrote:
> 
> 
> On 19.06.20 00:22, Collin Walling wrote:
>> Rework the SCLP boundary check to account for different SCLP commands
>> (eventually) allowing different boundary sizes.
>>
>> Move the length check code into a separate function, and introduce a
>> new function to determine the length of the read SCP data (i.e. the size
>> from the start of the struct to where the CPU entries should begin).
>>
>> The format of read CPU info is unlikely to change in the future,
>> so we do not require a separate function to calculate its length.
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  hw/s390x/sclp.c | 59 -
>>  1 file changed, 49 insertions(+), 10 deletions(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 181ce04007..0710138f91 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -49,6 +49,34 @@ static inline bool sclp_command_code_valid(uint32_t code)
>>  return false;
>>  }
>>  
>> +static bool sccb_has_valid_boundary(uint64_t sccb_addr, uint32_t code,
>> +SCCBHeader *header)
> 
> As you write to the sccb in case of error, mabye
> sccb_verify_boundary instead of has_valid. has_valid feels like a read-only 
> function.
> 
>> +{
>> +uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(header->length) - 1;
>> +uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>> +
>> +switch (code & SCLP_CMD_CODE_MASK) {
>> +default:
>> +if (sccb_max_addr < sccb_boundary) {
>> +return true;
>> +}
>> +}
>> +header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>> +return false;
>> +}
>> +
>> +/* Calculates sufficient SCCB length to store a full Read SCP/CPU response 
>> */
>> +static bool sccb_sufficient_len(SCCB *sccb, int num_cpus, int data_len)
> 
> same here, maybe sccb_verify_length

Sounds good. I was struggling with a decent naming scheme for these as
well :)

> 
>> +{
>> +int required_len = data_len + num_cpus * sizeof(CPUEntry);
>> +
>> +if (be16_to_cpu(sccb->h.length) < required_len) {
>> +sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +return false;
>> +}
>> +return true;
>> +}
>> +
>>  static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int 
>> *count)
>>  {
>>  uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
>> @@ -66,6 +94,16 @@ static void prepare_cpu_entries(MachineState *ms, 
>> CPUEntry *entry, int *count)
>>  }
>>  }
>>  
>> +/*
>> + * The data length denotes the start of the struct to where the first
>> + * CPU entry is to be allocated. This value also denotes the offset_cpu
>> + * field.
>> + */
>> +static inline int get_read_scp_info_data_len(void)
>> +{
>> +return offsetof(ReadInfo, entries);
>> +}
>> +
>>  /* Provide information about the configuration, CPUs and storage */
>>  static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  {
>> @@ -74,17 +112,16 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  int cpu_count;
>>  int rnsize, rnmax;
>>  IplParameterBlock *ipib = s390_ipl_get_iplb();
>> +int data_len = get_read_scp_info_data_len();
>>  
>> -if (be16_to_cpu(sccb->h.length) <
>> -  (sizeof(ReadInfo) + machine->possible_cpus->len * 
>> sizeof(CPUEntry))) {
>> -sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +if (!sccb_sufficient_len(sccb, machine->possible_cpus->len, data_len)) {
>>  return;
>>  }
>>  
>>  /* CPU information */
>>  prepare_cpu_entries(machine, read_info->entries, _count);
>>  read_info->entries_cpu = cpu_to_be16(cpu_count);
>> -read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
>> +read_info->offset_cpu = cpu_to_be16(data_len);
>>  read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
>>  
>>  read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
>> @@ -133,17 +170,16 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
>> *sccb)
>>  {
>>  MachineState *machine = MACHINE(qdev_get_machine());
>>  ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
>> +int data_len = offsetof(ReadCpuInfo,

[PATCH v3 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-06-18 Thread Collin Walling
As more features and facilities are added to the Read SCP Info (RSCPI)
response, more space is required to store them. The space used to store
these new features intrudes on the space originally used to store CPU
entries. This means as more features and facilities are added to the
RSCPI response, less space can be used to store CPU entries.

With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
the RSCPI command and determine if the SCCB is large enough to store a
complete reponse. If it is not large enough, then the required length
will be set in the SCCB header.

The caller of the SCLP command is responsible for creating a
large-enough SCCB to store a complete response. Proper checking should
be in place, and the caller should execute the command once-more with
the large-enough SCCB.

This facility also enables an extended SCCB for the Read CPU Info
(RCPUI) command.

When this facility is enabled, the boundary violation response cannot
be a result from the RSCPI, RSCPI Forced, or RCPUI commands.

In order to tolerate kernels that do not yet have full support for this
feature, a "fixed" offset to the start of the CPU Entries within the
Read SCP Info struct is set to allow for the original 248 max entries
when this feature is disabled.

Additionally, this is introduced as a CPU feature to protect the guest
from migrating to a machine that does not support storing an extended
SCCB. This could otherwise hinder the VM from being able to read all
available CPU entries after migration (such as during re-ipl).

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c | 21 -
 include/hw/s390x/sclp.h |  1 +
 target/s390x/cpu_features_def.inc.h |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  |  8 
 5 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 0dfbe6e5ec..f7c49e339e 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -56,6 +56,18 @@ static bool sccb_has_valid_boundary(uint64_t sccb_addr, 
uint32_t code,
 uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
 
 switch (code & SCLP_CMD_CODE_MASK) {
+case SCLP_CMDW_READ_SCP_INFO:
+case SCLP_CMDW_READ_SCP_INFO_FORCED:
+case SCLP_CMDW_READ_CPU_INFO:
+/*
+ * An extended-length SCCB is only allowed for Read SCP/CPU Info and
+ * is allowed to exceed the 4k boundary. The respective commands will
+ * set the length field to the required length if an insufficient
+ * SCCB length is provided.
+ */
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+return true;
+}
 default:
 if (sccb_max_addr < sccb_boundary) {
 return true;
@@ -72,6 +84,10 @@ static bool sccb_sufficient_len(SCCB *sccb, int num_cpus, 
int data_len)
 
 if (be16_to_cpu(sccb->h.length) < required_len) {
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
+sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) {
+sccb->h.length = required_len;
+}
 return false;
 }
 return true;
@@ -101,7 +117,9 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
  */
 static inline int get_read_scp_info_data_len(void)
 {
-return offsetof(ReadInfo, entries);
+return s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
+   offsetof(ReadInfo, entries) :
+   SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET;
 }
 
 /* Provide information about the configuration, CPUs and storage */
@@ -116,6 +134,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 CPUEntry *entries_start = (void *)sccb + data_len;
 
 if (!sccb_sufficient_len(sccb, machine->possible_cpus->len, data_len)) {
+warn_report("insufficient sccb size to store read scp info response");
 return;
 }
 
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 822eff4396..ef2d63eae9 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -110,6 +110,7 @@ typedef struct CPUEntry {
 uint8_t reserved1;
 } QEMU_PACKED CPUEntry;
 
+#define SCLP_READ_SCP_INFO_FIXED_CPU_OFFSET 128
 typedef struct ReadInfo {
 SCCBHeader h;
 uint16_t rnmax;
diff --git a/target/s390x/cpu_features_def.inc.h 
b/target/s390x/cpu_features_def.inc.h
index 5942f81f16..1c04cc18f4 100644
--- a/target/s390x/cpu_features_def.inc.h
+++ b/target/s390x/cpu_features_def.inc.h
@@ -97,6 +97,7 @@ DEF_FEAT(GUARDED_STORAGE, "gs", STFL, 133, "Guarded-storage 
facility")
 DEF_FEAT(VECTOR_PACKED_DECIMAL, "vxpd", STFL, 134, "Vector packed decimal 
facility")
 DEF_FEAT(VECTOR_ENH, "vxeh", STFL, 135, "Vector enhancements facility")
 DEF_FEAT(MULTIPLE_EP

[PATCH v3 5/8] s390/sclp: use cpu offset to locate cpu entries

2020-06-18 Thread Collin Walling
The start of the CPU entry region in the Read SCP Info response data is
denoted by the offset_cpu field. As such, QEMU needs to begin creating
entries at this address. Note that the length of the Read SCP Info data
(data_len) denotes the same value as the cpu offset.

This is in preparation of when Read SCP Info inevitably introduces new
bytes that push the start of the CPUEntry field further away.

Read CPU Info is unlikely to ever change, so let's not bother
accounting for the offset there.

Signed-off-by: Collin Walling 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 772b7b3b01..0dfbe6e5ec 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -113,13 +113,14 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 int data_len = get_read_scp_info_data_len();
+CPUEntry *entries_start = (void *)sccb + data_len;
 
 if (!sccb_sufficient_len(sccb, machine->possible_cpus->len, data_len)) {
 return;
 }
 
 /* CPU information */
-prepare_cpu_entries(machine, read_info->entries, _count);
+prepare_cpu_entries(machine, entries_start, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(data_len);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
-- 
2.21.3




[PATCH v3 8/8] s390: guest support for diagnose 0x318

2020-06-18 Thread Collin Walling
DIAGNOSE 0x318 (diag318) is an s390 instruction that allows the storage
of diagnostic information that is collected by the firmware in the case
of hardware/firmware service events.

QEMU handles the instruction by storing the info in the CPU state. A
subsequent register sync will communicate the data to the hypervisor.

QEMU handles the migration via a VM State Description.

This feature depends on the Extended-Length SCCB (els) feature. If
els is not present, then a warning will be printed and the SCLP bit
that allows the Linux kernel to execute the instruction will not be
set.

Availability of this instruction is determined by byte 134 (aka fac134)
bit 0 of the SCLP Read Info block. This coincidentally expands into the
space used for CPU entries, which means VMs running with the diag318
capability may not be able to read information regarding all CPUs
unless the guest kernel supports an extended-length SCCB.

This feature is not supported in protected virtualization mode.

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c |  5 +
 include/hw/s390x/sclp.h |  3 +++
 target/s390x/cpu.h  |  3 ++-
 target/s390x/cpu_features.h |  1 +
 target/s390x/cpu_features_def.inc.h |  3 +++
 target/s390x/cpu_models.c   |  1 +
 target/s390x/gen-features.c |  1 +
 target/s390x/kvm.c  | 31 +
 target/s390x/machine.c  | 17 
 9 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index f7c49e339e..78dbfbe427 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -152,6 +152,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
  read_info->conf_char_ext);
 
+if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
+s390_get_feat_block(S390_FEAT_TYPE_SCLP_FAC134,
+_info->fac134);
+}
+
 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 ef2d63eae9..ccb9f0a676 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -133,6 +133,9 @@ typedef struct ReadInfo {
 uint16_t highest_cpu;
 uint8_t  _reserved5[124 - 122]; /* 122-123 */
 uint32_t hmfai;
+uint8_t  _reserved7[134 - 128]; /* 128-133 */
+uint8_t  fac134;
+uint8_t  _reserved8[144 - 135]; /* 135-143 */
 struct CPUEntry entries[];
 } QEMU_PACKED ReadInfo;
 
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 035427521c..52765961cf 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -112,6 +112,8 @@ struct CPUS390XState {
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 
+uint64_t diag318_info;
+
 /* Fields up to this point are cleared by a CPU reset */
 struct {} end_reset_fields;
 
@@ -136,7 +138,6 @@ struct CPUS390XState {
 
 /* currently processed sigp order */
 uint8_t sigp_order;
-
 };
 
 static inline uint64_t *get_freg(CPUS390XState *cs, int nr)
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index da695a8346..f74f7fc3a1 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_FAC134,
 S390_FEAT_TYPE_SCLP_CPU,
 S390_FEAT_TYPE_MISC,
 S390_FEAT_TYPE_PLO,
diff --git a/target/s390x/cpu_features_def.inc.h 
b/target/s390x/cpu_features_def.inc.h
index 1c04cc18f4..f82b4b5ec1 100644
--- a/target/s390x/cpu_features_def.inc.h
+++ b/target/s390x/cpu_features_def.inc.h
@@ -122,6 +122,9 @@ DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: 
Collaborative-memory-man
 DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation 
facility")
 DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: 
Interlock-and-broadcast-suppression facility")
 
+/* Features exposed via SCLP SCCB Facilities byte 134 (bit numbers relative to 
byte-134) */
+DEF_FEAT(DIAG_318, "diag318", SCLP_FAC134, 0, "Control program name and 
version codes")
+
 /* Features exposed via SCLP CPU info. */
 DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual 
SIE)")
 DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 2fa609bffe..034673be54 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -827,6 +827,7 @@ static void check_consistency(const S390CPUModel *model)
 { S390_FEAT_PTFF_STOE, S390_FEAT_MULTIPLE_EPOCH },
 { S390_FEAT_PTFF_STOUE

[PATCH v3 7/8] s390/kvm: header sync for diag318

2020-06-18 Thread Collin Walling
Signed-off-by: Collin Walling 
---
 linux-headers/asm-s390/kvm.h | 5 -
 linux-headers/linux/kvm.h| 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 0138ccb0d8..98665dff19 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+#define KVM_SYNC_DIAG318 (1UL << 12)
 
 #define KVM_SYNC_S390_VALID_FIELDS \
(KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
 KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
-KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
+KVM_SYNC_DIAG318)
 
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
@@ -254,6 +256,7 @@ struct kvm_sync_regs {
__u64 pft;  /* pfault token [PFAULT] */
__u64 pfs;  /* pfault select [PFAULT] */
__u64 pfc;  /* pfault compare [PFAULT] */
+   __u64 diag318;  /* diagnose 0x318 info */
union {
__u64 vrs[32][2];   /* vector registers (KVM_SYNC_VRS) */
__u64 fprs[16]; /* fp registers (KVM_SYNC_FPRS) */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 9804495a46..444fdd977f 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1017,6 +1017,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_VCPU_RESETS 179
 #define KVM_CAP_S390_PROTECTED 180
 #define KVM_CAP_PPC_SECURE_GUEST 181
+#define KVM_CAP_S390_DIAG318 184
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.21.3




[PATCH v3 1/8] s390/sclp: get machine once during read scp/cpu info

2020-06-18 Thread Collin Walling
Functions within read scp/cpu info will need access to the machine
state. Let's make a call to retrieve the machine state once and
pass the appropriate data to the respective functions.

Signed-off-by: Collin Walling 
Reviewed-by: David Hildenbrand 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 20aca30ac4..7875334037 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,9 +49,8 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
-static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
+static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
 int i;
 
@@ -77,7 +76,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
 /* CPU information */
-prepare_cpu_entries(sclp, read_info->entries, _count);
+prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
 read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
@@ -132,10 +131,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 /* Provide information about the CPU */
 static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
 {
+MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(sclp, cpu_info->entries, _count);
+prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
 cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
 cpu_info->nr_standby = cpu_to_be16(0);
-- 
2.21.3




[PATCH v3 4/8] s390/sclp: read sccb from mem based on sccb length

2020-06-18 Thread Collin Walling
The header of the SCCB contains the actual length of the SCCB. Instead
of using a static 4K size, let's allow for a variable size determined
by the value set in the header. The proper checks are already in place
to ensure the SCCB length is sufficent to store a full response, and
that the length does not cross any explicitly-set boundaries.

Signed-off-by: Collin Walling 
Reviewed-by: Thomas Huth 
---
 hw/s390x/sclp.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 0710138f91..772b7b3b01 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -256,9 +256,8 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 SCLPDevice *sclp = get_sclp_device();
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 SCCB work_sccb;
-hwaddr sccb_len = sizeof(SCCB);
 
-s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sccb_len);
+s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb, sizeof(SCCBHeader));
 
 if (!sclp_command_code_valid(code)) {
 work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
@@ -269,6 +268,9 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+s390_cpu_pv_mem_read(env_archcpu(env), 0, _sccb,
+ be16_to_cpu(work_sccb.h.length));
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -283,8 +285,6 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
 SCCB work_sccb;
 
-hwaddr sccb_len = sizeof(SCCB);
-
 /* first some basic checks on program checks */
 if (env->psw.mask & PSW_MASK_PSTATE) {
 return -PGM_PRIVILEGED;
@@ -302,7 +302,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
  * from playing dirty tricks by modifying the memory content after
  * the host has checked the values
  */
-cpu_physical_memory_read(sccb, _sccb, sccb_len);
+cpu_physical_memory_read(sccb, _sccb, sizeof(SCCBHeader));
 
 /* Valid sccb sizes */
 if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
@@ -318,6 +318,9 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
+/* the header contains the actual length of the sccb */
+cpu_physical_memory_read(sccb, _sccb, 
be16_to_cpu(work_sccb.h.length));
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 cpu_physical_memory_write(sccb, _sccb,
-- 
2.21.3




[PATCH v3 3/8] s390/sclp: rework sclp boundary and length checks

2020-06-18 Thread Collin Walling
Rework the SCLP boundary check to account for different SCLP commands
(eventually) allowing different boundary sizes.

Move the length check code into a separate function, and introduce a
new function to determine the length of the read SCP data (i.e. the size
from the start of the struct to where the CPU entries should begin).

The format of read CPU info is unlikely to change in the future,
so we do not require a separate function to calculate its length.

Signed-off-by: Collin Walling 
---
 hw/s390x/sclp.c | 59 -
 1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 181ce04007..0710138f91 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -49,6 +49,34 @@ static inline bool sclp_command_code_valid(uint32_t code)
 return false;
 }
 
+static bool sccb_has_valid_boundary(uint64_t sccb_addr, uint32_t code,
+SCCBHeader *header)
+{
+uint64_t sccb_max_addr = sccb_addr + be16_to_cpu(header->length) - 1;
+uint64_t sccb_boundary = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
+
+switch (code & SCLP_CMD_CODE_MASK) {
+default:
+if (sccb_max_addr < sccb_boundary) {
+return true;
+}
+}
+header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+return false;
+}
+
+/* Calculates sufficient SCCB length to store a full Read SCP/CPU response */
+static bool sccb_sufficient_len(SCCB *sccb, int num_cpus, int data_len)
+{
+int required_len = data_len + num_cpus * sizeof(CPUEntry);
+
+if (be16_to_cpu(sccb->h.length) < required_len) {
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return false;
+}
+return true;
+}
+
 static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count)
 {
 uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
@@ -66,6 +94,16 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry 
*entry, int *count)
 }
 }
 
+/*
+ * The data length denotes the start of the struct to where the first
+ * CPU entry is to be allocated. This value also denotes the offset_cpu
+ * field.
+ */
+static inline int get_read_scp_info_data_len(void)
+{
+return offsetof(ReadInfo, entries);
+}
+
 /* Provide information about the configuration, CPUs and storage */
 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 {
@@ -74,17 +112,16 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int cpu_count;
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
+int data_len = get_read_scp_info_data_len();
 
-if (be16_to_cpu(sccb->h.length) <
-  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (!sccb_sufficient_len(sccb, machine->possible_cpus->len, data_len)) {
 return;
 }
 
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
-read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
+read_info->offset_cpu = cpu_to_be16(data_len);
 read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
@@ -133,17 +170,16 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
+int data_len = offsetof(ReadCpuInfo, entries);
 int cpu_count;
 
-if (be16_to_cpu(sccb->h.length) <
-  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+if (!sccb_sufficient_len(sccb, machine->possible_cpus->len, data_len)) {
 return;
 }
 
 prepare_cpu_entries(machine, cpu_info->entries, _count);
 cpu_info->nr_configured = cpu_to_be16(cpu_count);
-cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
+cpu_info->offset_configured = cpu_to_be16(data_len);
 cpu_info->nr_standby = cpu_to_be16(0);
 
 /* The standby offset is 16-byte for each CPU */
@@ -229,6 +265,10 @@ int sclp_service_call_protected(CPUS390XState *env, 
uint64_t sccb,
 goto out_write;
 }
 
+if (!sccb_has_valid_boundary(sccb, code, _sccb.h)) {
+goto out_write;
+}
+
 sclp_c->execute(sclp, _sccb, code);
 out_write:
 s390_cpu_pv_mem_write(env_archcpu(env), 0, _sccb,
@@ -274,8 +314,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, 
uint32_t code)
 goto out_write;
 }
 
-if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + 
PAGE_SIZE)) {
-work_sccb.h.response_code = 
cpu_to_be16(S

[PATCH v3 2/8] s390/sclp: check sccb len before filling in data

2020-06-18 Thread Collin Walling
The SCCB must be checked for a sufficient length before it is filled
with any data. If the length is insufficient, then the SCLP command
is suppressed and the proper response code is set in the SCCB header.

Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length")
Signed-off-by: Collin Walling 
Reviewed-by: Janosch Frank 
---
 hw/s390x/sclp.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 7875334037..181ce04007 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -75,6 +75,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 int rnsize, rnmax;
 IplParameterBlock *ipib = s390_ipl_get_iplb();
 
+if (be16_to_cpu(sccb->h.length) <
+  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
+sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
+return;
+}
+
 /* CPU information */
 prepare_cpu_entries(machine, read_info->entries, _count);
 read_info->entries_cpu = cpu_to_be16(cpu_count);
@@ -83,12 +89,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
 
 read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
 
-if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
-sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
-return;
-}
-
 /* Configuration Characteristic (Extension) */
 s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
  read_info->conf_char);
@@ -135,17 +135,17 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
*sccb)
 ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
 int cpu_count;
 
-prepare_cpu_entries(machine, cpu_info->entries, _count);
-cpu_info->nr_configured = cpu_to_be16(cpu_count);
-cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
-cpu_info->nr_standby = cpu_to_be16(0);
-
 if (be16_to_cpu(sccb->h.length) <
-(sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
+  (sizeof(ReadInfo) + machine->possible_cpus->len * sizeof(CPUEntry))) 
{
 sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
 return;
 }
 
+prepare_cpu_entries(machine, cpu_info->entries, _count);
+cpu_info->nr_configured = cpu_to_be16(cpu_count);
+cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
+cpu_info->nr_standby = cpu_to_be16(0);
+
 /* The standby offset is 16-byte for each CPU */
 cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
 + cpu_info->nr_configured*sizeof(CPUEntry));
-- 
2.21.3




[PATCH v3 0/8] s390: Extended-Length SCCB & DIAGNOSE 0x318

2020-06-18 Thread Collin Walling
Changelog:

v3

• Device IOCTLs removed
- diag 318 info is now communicated via sync_regs

• Reset code removed
- this is now handled in KVM
- diag318_info is stored within the CPU reset portion of the
S390CPUState

• Various cleanups for ELS preliminary patches

v2

• QEMU now handles the instruction call
- as such, the "enable diag 318" IOCTL has been removed

• patch #1 now changes the read scp/cpu info functions to
  retrieve the machine state once
- as such, I have not added any ack's or r-bs since this
  patch differs from the previous version

• patch #3 introduces a new "get_read_scp_info_data_len"
  function in order clean-up the variable data length assignment
  in patch #7
- a comment above this function should help clarify what's
  going on to make things a bit easier to read

• other misc clean ups and fixes
- s/diag318/diag_318 in order to keep the naming scheme
  consistent with Linux and other diag-related code
- s/byte_134/fac134 to align naming scheme with Linux

---

This patch series introduces two features for an s390 KVM quest:
- Extended-Length SCCB (els) for the Read SCP/CPU Info SCLP 
commands
- DIAGNOSE 0x318 (diag_318) enabling / migration handling

The diag 318 feature depends on els and KVM support.

The els feature is handled entirely with QEMU, and does not require 
KVM support.

Both features are made available starting with the zEC12-full model.

These patches are introduced together for two main reasons:
- els allows diag 318 to exist while retaining the original 248 
VCPU max
- diag 318 is presented to show how els is useful

Full els support is dependant on the Linux kernel, which must react
to the SCLP response code and set an appropriate-length SCCB. 

A user should take care when tuning the CPU model for a VM.
If a user defines a VM with els support and specifies 248 CPUs, but
the guest Linux kernel cannot react to the SCLP response code, then
the guest will crash immediately upon kernel startup.

Collin L. Walling (8):
  s390/sclp: get machine once during read scp/cpu info
  s390/sclp: check sccb len before filling in data
  s390/sclp: rework sclp boundary and length checks
  s390/sclp: read sccb from mem based on sccb length
  s390/sclp: use cpu offset to locate cpu entries
  s390/sclp: add extended-length sccb support for kvm guest
  s390/kvm: header sync for diag318
  s390: guest support for diagnose 0x318

 hw/s390x/sclp.c | 117 ++--
 include/hw/s390x/sclp.h |   4 +
 linux-headers/asm-s390/kvm.h|   5 +-
 linux-headers/linux/kvm.h   |   1 +
 target/s390x/cpu.h  |   3 +-
 target/s390x/cpu_features.h |   1 +
 target/s390x/cpu_features_def.inc.h |   4 +
 target/s390x/cpu_models.c   |   1 +
 target/s390x/gen-features.c |   2 +
 target/s390x/kvm.c  |  39 ++
 target/s390x/machine.c  |  17 
 11 files changed, 167 insertions(+), 27 deletions(-)

-- 
2.21.3




Re: [PATCH v2 2/8] s390/sclp: check sccb len before filling in data

2020-06-15 Thread Collin Walling
On 6/11/20 8:01 AM, Thomas Huth wrote:
> On 16/05/2020 00.20, Collin Walling wrote:
>> The SCCB must be checked for a sufficient length before it is filled
>> with any data. If the length is insufficient, then the SCLP command
>> is suppressed and the proper response code is set in the SCCB header.
>>
>> Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length")
>> Signed-off-by: Collin Walling 
>> ---
>>  hw/s390x/sclp.c | 22 ++
>>  1 file changed, 10 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 61e2e2839c..2bd618515e 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -75,6 +75,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  int rnsize, rnmax;
>>  IplParameterBlock *ipib = s390_ipl_get_iplb();
>>  
>> +if (be16_to_cpu(sccb->h.length) < (sizeof(ReadInfo) + cpu_count * 
>> sizeof(CPUEntry))) {
> 
> You are using cpu_count here ...
> 
>> +sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +return;
>> +}
>> +
>>  /* CPU information */
>>  prepare_cpu_entries(machine, read_info->entries, _count);
> 
> ... but it is only initialized here.
> 
> Even if you replace the code in a later patch, please fix this here,
> too, to maintain bisectability of the code.
> 
>>  read_info->entries_cpu = cpu_to_be16(cpu_count);
>> @@ -83,12 +88,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  
>>  read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
>>  
>> -if (be16_to_cpu(sccb->h.length) <
>> -(sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
>> -sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> -return;
>> -}
>> -
>>  /* Configuration Characteristic (Extension) */
>>  s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
>>   read_info->conf_char);
>> @@ -135,17 +134,16 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
>> *sccb)
>>  ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
>>  int cpu_count;
>>  
>> +if (be16_to_cpu(sccb->h.length) < (sizeof(ReadCpuInfo) + cpu_count * 
>> sizeof(CPUEntry))) {
> 
> dito!
> 
>> +sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +return;
>> +}
>> +
>>  prepare_cpu_entries(machine, cpu_info->entries, _count);
>>  cpu_info->nr_configured = cpu_to_be16(cpu_count);
>>  cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, 
>> entries));
>>  cpu_info->nr_standby = cpu_to_be16(0);
>>  
>> -if (be16_to_cpu(sccb->h.length) <
>> -(sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
>> -sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> -return;
>> -}
>> -
>>  /* The standby offset is 16-byte for each CPU */
>>  cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
>>  + cpu_info->nr_configured*sizeof(CPUEntry));
> 
>  Thanks,
>   Thomas
> 

I'll rework this patch. Thanks for the reviews!

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v2 3/8] s390/sclp: rework sclp boundary and length checks

2020-06-15 Thread Collin Walling
On 6/11/20 8:56 AM, Thomas Huth wrote:
> On 16/05/2020 00.20, Collin Walling wrote:
>> Rework the SCLP boundary check to account for different SCLP commands
>> (eventually) allowing different boundary sizes.
>>
>> Move the length check code into a separate function, and introduce a
>> new function to determine the length of the read SCP data (i.e. the size
>> from the start of the struct to where the CPU entries should begin).
>>
>> Signed-off-by: Collin Walling 
>> ---
>>  hw/s390x/sclp.c | 57 ++---
>>  1 file changed, 49 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index 2bd618515e..987699e3c4 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -49,6 +49,34 @@ static inline bool sclp_command_code_valid(uint32_t code)
>>  return false;
>>  }
>>  
>> +static bool sccb_has_valid_boundary(uint64_t sccb_addr, uint32_t code,
>> +SCCBHeader *header)
>> +{
>> +uint64_t current_len = sccb_addr + be16_to_cpu(header->length);
>> +uint64_t allowed_len = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>> +
>> +switch (code & SCLP_CMD_CODE_MASK) {
>> +default:
>> +if (current_len <= allowed_len) {
>> +return true;
>> +}
>> +}
>> +header->response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
>> +return false;
>> +}
>> +
>> +/* Calculates sufficient SCCB length to store a full Read SCP/CPU response 
>> */
>> +static bool sccb_has_sufficient_len(SCCB *sccb, int num_cpus, int data_len)
>> +{
>> +int required_len = data_len + num_cpus * sizeof(CPUEntry);
>> +
>> +if (be16_to_cpu(sccb->h.length) < required_len) {
>> +sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +return false;
>> +}
>> +return true;
>> +}
>> +
>>  static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int 
>> *count)
>>  {
>>  uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
>> @@ -66,6 +94,16 @@ static void prepare_cpu_entries(MachineState *ms, 
>> CPUEntry *entry, int *count)
>>  }
>>  }
>>  
>> +/*
>> + * The data length denotes the start of the struct to where the first
>> + * CPU entry is to be allocated. This value also denotes the offset_cpu
>> + * field.
>> + */
>> +static int get_read_scp_info_data_len(void)
>> +{
>> +return offsetof(ReadInfo, entries);
>> +}
>> +
>>  /* Provide information about the configuration, CPUs and storage */
>>  static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  {
>> @@ -74,16 +112,16 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
>>  int cpu_count;
>>  int rnsize, rnmax;
>>  IplParameterBlock *ipib = s390_ipl_get_iplb();
>> +int data_len = get_read_scp_info_data_len();
>>  
>> -if (be16_to_cpu(sccb->h.length) < (sizeof(ReadInfo) + cpu_count * 
>> sizeof(CPUEntry))) {
>> -sccb->h.response_code = 
>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>> +if (!sccb_has_sufficient_len(sccb, machine->possible_cpus->len, 
>> data_len)) {
>>  return;
>>  }
>>  
>>  /* CPU information */
>>  prepare_cpu_entries(machine, read_info->entries, _count);
>>  read_info->entries_cpu = cpu_to_be16(cpu_count);
>> -read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
>> +read_info->offset_cpu = cpu_to_be16(data_len);
>>  read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
>>  
>>  read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
>> @@ -132,16 +170,16 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB 
>> *sccb)
>>  {
>>  MachineState *machine = MACHINE(qdev_get_machine());
>>  ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
>> +int data_len = offsetof(ReadCpuInfo, entries);
> 
> Is there a reason for not using get_read_scp_info_data_len() here?
> 
>  Thomas
> 
> 

That function is for Read SCP Info.

Read CPU Info does not face the complications that come with new
features intruding on the space used for CPU entries (thankfully), so
there's no need for a function to determine its data length.

-- 
Regards,
Collin

Stay safe and stay healthy



Re: [PATCH v2 6/8] s390/sclp: add extended-length sccb support for kvm guest

2020-05-26 Thread Collin Walling
On 5/25/20 6:50 AM, Janosch Frank wrote:
> On 5/18/20 4:31 PM, Collin Walling wrote:
>> On 5/18/20 4:55 AM, Janosch Frank wrote:
>>> On 5/16/20 12:20 AM, Collin Walling wrote:
>>>> As more features and facilities are added to the Read SCP Info (RSCPI)
>>>> response, more space is required to store them. The space used to store
>>>> these new features intrudes on the space originally used to store CPU
>>>> entries. This means as more features and facilities are added to the
>>>> RSCPI response, less space can be used to store CPU entries.
>>>>
>>>> With the Extended-Length SCCB (ELS) facility, a KVM guest can execute
>>>> the RSCPI command and determine if the SCCB is large enough to store a
>>>> complete reponse. If it is not large enough, then the required length
>>>> will be set in the SCCB header.
>>>>
>>>> The caller of the SCLP command is responsible for creating a
>>>> large-enough SCCB to store a complete response. Proper checking should
>>>> be in place, and the caller should execute the command once-more with
>>>> the large-enough SCCB.
>>>>
>>>> This facility also enables an extended SCCB for the Read CPU Info
>>>> (RCPUI) command.
>>>>
>>>> When this facility is enabled, the boundary violation response cannot
>>>> be a result from the RSCPI, RSCPI Forced, or RCPUI commands.
>>>>
>>>> In order to tolerate kernels that do not yet have full support for this
>>>> feature, a "fixed" offset to the start of the CPU Entries within the
>>>> Read SCP Info struct is set to allow for the original 248 max entries
>>>> when this feature is disabled.
>>>>
>>>> Additionally, this is introduced as a CPU feature to protect the guest
>>>> from migrating to a machine that does not support storing an extended
>>>> SCCB. This could otherwise hinder the VM from being able to read all
>>>> available CPU entries after migration (such as during re-ipl).
>>>>
>>>> Signed-off-by: Collin Walling 
>>>> ---
>>>>  hw/s390x/sclp.c | 21 -
>>>>  include/hw/s390x/sclp.h |  1 +
>>>>  target/s390x/cpu_features_def.inc.h |  1 +
>>>>  target/s390x/gen-features.c |  1 +
>>>>  target/s390x/kvm.c  |  4 
>>>>  5 files changed, 27 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>>>> index 755f5f3fab..bde4c5420e 100644
>>>> --- a/hw/s390x/sclp.c
>>>> +++ b/hw/s390x/sclp.c
>>>> @@ -56,6 +56,18 @@ static bool sccb_has_valid_boundary(uint64_t sccb_addr, 
>>>> uint32_t code,
>>>>  uint64_t allowed_len = (sccb_addr & PAGE_MASK) + PAGE_SIZE;
>>>>  
>>>>  switch (code & SCLP_CMD_CODE_MASK) {
>>>> +case SCLP_CMDW_READ_SCP_INFO:
>>>> +case SCLP_CMDW_READ_SCP_INFO_FORCED:
>>>> +case SCLP_CMDW_READ_CPU_INFO:
>>>> +/*
>>>> + * An extended-length SCCB is only allowed for RSCPI and RSCPU 
>>>> and is
>>>> + * allowed to exceed the 4k boundary. The respective commands will
>>>> + * set the length field to the required length if an insufficient
>>>> + * SCCB length is provided.
>>>> + */
>>>> +if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB)) {
>>>> +return true;
>>>> +}
>>>>  default:
>>>>  if (current_len <= allowed_len) {
>>>>  return true;
>>>> @@ -72,6 +84,10 @@ static bool sccb_has_sufficient_len(SCCB *sccb, int 
>>>> num_cpus, int data_len)
>>>>  
>>>>  if (be16_to_cpu(sccb->h.length) < required_len) {
>>>>  sccb->h.response_code = 
>>>> cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
>>>> +if (s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) &&
>>>> +sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) {
>>>> +sccb->h.length = required_len;
>>>> +}
>>>>  return false;
>>>>  }
>>>>  return true;
>>>> @@ -101,7 +117,9 @@ static void prepare_cpu_entries(MachineState *ms, 
>>>> CPUEntry *entry, int *count)
>>>>   

  1   2   3   >