[15/15] s390x: protvirt: Handle SIGP store status correctly
diff mbox series

Message ID 20191120114334.2287-16-frankja@linux.ibm.com
State New
Headers show
Series
  • s390x: Protected Virtualization support
Related show

Commit Message

Janosch Frank Nov. 20, 2019, 11:43 a.m. UTC
Status storing is obviously not done by qemu anymore.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
 target/s390x/sigp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

David Hildenbrand Nov. 21, 2019, 11:24 a.m. UTC | #1
On 20.11.19 12:43, Janosch Frank wrote:
> Status storing is obviously not done by qemu anymore.
> 
> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
> ---
>   target/s390x/sigp.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
> index 2ce22d4dc1..68634d694a 100644
> --- a/target/s390x/sigp.c
> +++ b/target/s390x/sigp.c
> @@ -144,7 +144,9 @@ static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
>       case S390_CPU_STATE_STOPPED:
>           /* already stopped, just store the status */
>           cpu_synchronize_state(cs);
> -        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
> +        if (!cpu->env.pv) {
> +            s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
> +        }

Confused, how is that case handled? The CPU is already stopped, so it 
won't be run again (consequently, next SIE entry can't store it). Who 
will store the status?

>           break;
>       }
>       si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
> @@ -497,7 +499,8 @@ void do_stop_interrupt(CPUS390XState *env)
>       if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
>           qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>       }
> -    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
> +    /* Storing will occur on next SIE entry for fmt 4 */
> +    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS && !env->pv) {
>           s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
>       }
>       env->sigp_order = 0;
>
Janosch Frank Nov. 21, 2019, 11:29 a.m. UTC | #2
On 11/21/19 12:24 PM, David Hildenbrand wrote:
> On 20.11.19 12:43, Janosch Frank wrote:
>> Status storing is obviously not done by qemu anymore.
>>
>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>> ---
>>   target/s390x/sigp.c | 7 +++++--
>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
>> index 2ce22d4dc1..68634d694a 100644
>> --- a/target/s390x/sigp.c
>> +++ b/target/s390x/sigp.c
>> @@ -144,7 +144,9 @@ static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
>>       case S390_CPU_STATE_STOPPED:
>>           /* already stopped, just store the status */
>>           cpu_synchronize_state(cs);
>> -        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
>> +        if (!cpu->env.pv) {
>> +            s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
>> +        }
> 
> Confused, how is that case handled? The CPU is already stopped, so it 
> won't be run again (consequently, next SIE entry can't store it). Who 
> will store the status?

Firmware does some magic

> 
>>           break;
>>       }
>>       si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
>> @@ -497,7 +499,8 @@ void do_stop_interrupt(CPUS390XState *env)
>>       if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
>>           qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>>       }
>> -    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
>> +    /* Storing will occur on next SIE entry for fmt 4 */
>> +    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS && !env->pv) {
>>           s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
>>       }
>>       env->sigp_order = 0;
>>
> 
>
Thomas Huth Nov. 28, 2019, 3:30 p.m. UTC | #3
On 20/11/2019 12.43, Janosch Frank wrote:
> Status storing is obviously not done by qemu anymore.
> 
> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
> ---
>  target/s390x/sigp.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
> index 2ce22d4dc1..68634d694a 100644
> --- a/target/s390x/sigp.c
> +++ b/target/s390x/sigp.c
> @@ -144,7 +144,9 @@ static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
>      case S390_CPU_STATE_STOPPED:
>          /* already stopped, just store the status */
>          cpu_synchronize_state(cs);
> -        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
> +        if (!cpu->env.pv) {
> +            s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
> +        }
>          break;
>      }
>      si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
> @@ -497,7 +499,8 @@ void do_stop_interrupt(CPUS390XState *env)
>      if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
>          qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>      }
> -    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
> +    /* Storing will occur on next SIE entry for fmt 4 */
> +    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS && !env->pv) {
>          s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
>      }
>      env->sigp_order = 0;
> 

Maybe move the check into the s390_store_status() function instead?

Anyway,
Reviewed-by: Thomas Huth <thuth@redhat.com>

Patch
diff mbox series

diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index 2ce22d4dc1..68634d694a 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -144,7 +144,9 @@  static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
     case S390_CPU_STATE_STOPPED:
         /* already stopped, just store the status */
         cpu_synchronize_state(cs);
-        s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
+        if (!cpu->env.pv) {
+            s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
+        }
         break;
     }
     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
@@ -497,7 +499,8 @@  void do_stop_interrupt(CPUS390XState *env)
     if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
     }
-    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
+    /* Storing will occur on next SIE entry for fmt 4 */
+    if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS && !env->pv) {
         s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
     }
     env->sigp_order = 0;