From: Pierre Morel <pmorel@linux.ibm.com>
To: qemu-devel@nongnu.org
Subject: Re: [PATCH v1 1/1] s390x: protvirt: SCLP interpretation
Date: Thu, 28 Nov 2019 14:05:34 +0100 [thread overview]
Message-ID: <77551bc9-d81c-4c56-e754-84ad44b8e2bd@linux.ibm.com> (raw)
In-Reply-To: <e73fcc10-14cd-512e-56c7-ca17bcbefff8@redhat.com>
On 2019-11-28 13:10, Thomas Huth wrote:
> On 28/11/2019 11.13, Pierre Morel wrote:
>> The SCLP protection handle some of the exceptions due to
>> mis-constructions of the SCLP Control Block (SCCB) by the guest and
>> provides notifications to the host when something gets wrong.
>> We currently do not handle these exceptions, letting all the work to the
>> firmware therefor, we only need to inject an external interrupt to the
>> guest.
>>
>> When the SCCB is correct, the S390x virtualisation protection copies
>> the SCLP Control Block (SCCB) from the guest inside the kernel to avoid
>> opening a direct access to the guest memory.
>> When accessing the kernel memory with standard s390_cpu_virt_mem_*
>> functions the host opens access to the SCCB shadow at address 0.
>>
>> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
>> ---
>> hw/s390x/sclp.c | 18 +++++++++++++
>> include/hw/s390x/sclp.h | 2 ++
>> target/s390x/kvm.c | 56 ++++++++++++++++++++++++++++++++++++++++-
>> 3 files changed, 75 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
>> index f57ce7b739..02e4e0146f 100644
>> --- a/hw/s390x/sclp.c
>> +++ b/hw/s390x/sclp.c
>> @@ -193,6 +193,24 @@ static void sclp_execute(SCLPDevice *sclp, SCCB
>> *sccb, uint32_t code)
>> }
>> }
>> +int sclp_service_call_protected(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);
>> +
>> + /* Protected guest SCCB is always seen at address 0 */
>
> Well, as far as I've understood it, the address is rather ignored (and
> you can only specify an offset into the 4k page)?
You can see it like this, then the offset is 0. However we give here an
address as argument.
>
>> + s390_cpu_virt_mem_read(env_archcpu(env), 0, 0, &work_sccb, sccb_len);
>> + sclp_c->execute(sclp, &work_sccb, code);
>> + s390_cpu_virt_mem_write(env_archcpu(env), 0, 0, &work_sccb,
>> + be16_to_cpu(work_sccb.h.length));
>> +
>> + sclp_c->service_interrupt(sclp, (uint64_t)&work_sccb);
>> + return 0;
>> +}
>> +
>> int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t
>> code)
>> {
>> SCLPDevice *sclp = get_sclp_device();
>> diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
>> index c54413b78c..c0a3faa37d 100644
>> --- a/include/hw/s390x/sclp.h
>> +++ b/include/hw/s390x/sclp.h
>> @@ -217,5 +217,7 @@ void s390_sclp_init(void);
>> void sclp_service_interrupt(uint32_t sccb);
>> void raise_irq_cpu_hotplug(void);
>> int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t
>> code);
>> +int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
>> + uint32_t code);
>> #endif
>> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
>> index 0c9d14b4b1..559f470f51 100644
>> --- a/target/s390x/kvm.c
>> +++ b/target/s390x/kvm.c
>> @@ -1170,7 +1170,14 @@ static int kvm_sclp_service_call(S390CPU *cpu,
>> struct kvm_run *run,
>> sccb = env->regs[ipbh0 & 0xf];
>> code = env->regs[(ipbh0 & 0xf0) >> 4];
>> - r = sclp_service_call(env, sccb, code);
>> + switch (run->s390_sieic.icptcode) {
>> + case ICPT_PV_INSTR:
>> + r = sclp_service_call_protected(env, sccb, code);
>> + break;
>> + default:
>> + r = sclp_service_call(env, sccb, code);
>> + break;
>> + }
>
> Why not simply
>
> if (run->s390_sieic.icptcode == ICPT_PV_INSTR) {
> r = sclp_service_call_protected(env, sccb, code);
> } else {
> r = sclp_service_call(env, sccb, code);
> }
>
> ... that's way short and easier to read. Or do you expect other
> icptcodes in the near future?
No you are right, it is better, I just like switches :)
>
>> if (r < 0) {
>> kvm_s390_program_interrupt(cpu, -r);
>> } else {
>> @@ -1575,6 +1582,47 @@ static int kvm_s390_handle_sigp(S390CPU *cpu,
>> uint8_t ipa1, uint32_t ipb)
>> return 0;
>> }
>> +static int handle_secure_notification(S390CPU *cpu, struct kvm_run
>> *run)
>> +{
>> + unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
>> + uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
>> +
>> + switch (ipa0) {
>> + case IPA0_SIGP: /* We get the notification that the guest stop */
>> + kvm_s390_handle_sigp(cpu, ipa1, run->s390_sieic.ipb);
>> + break;
>> + case IPA0_B2: /* We accept but do nothing for B2 notifications */
>> + break;
>> + default: /* We do not expect other instruction's notification */
>> + kvm_s390_program_interrupt(cpu, PGM_OPERATION);
>
> Maybe add a tracepoint or qemu_log_mask(LOG_UNIMP, ...) or CPU_LOG_INT
> here, so we can spot this condition more easily?
>
>> + break;
>> + }
>> + return 0;
>> +}
>> +
>> +static int handle_secure_instruction(S390CPU *cpu, struct kvm_run *run)
>> +{
>> + unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
>> + uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
>> + int r = -1;
>> +
>> + switch (ipa0) {
>> + case IPA0_B2:
>> + r = handle_b2(cpu, run, ipa1);
>> + break;
>> + case IPA0_DIAG:
>> + r = handle_diag(cpu, run, run->s390_sieic.ipb);
>> + break;
>> + }
>> +
>> + if (r < 0) {
>> + r = 0;
>> + kvm_s390_program_interrupt(cpu, PGM_OPERATION);
>> + }
>> +
>> + return r;
>> +}
>> +
>> static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
>> {
>> unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
>> @@ -1665,6 +1713,12 @@ static int handle_intercept(S390CPU *cpu)
>> DPRINTF("intercept: 0x%x (at 0x%lx)\n", icpt_code,
>> (long)cs->kvm_run->psw_addr);
>> switch (icpt_code) {
>> + case ICPT_PV_INSTR_NOT:
>> + r = handle_secure_notification(cpu, run);
>> + break;
>> + case ICPT_PV_INSTR:
>> + r = handle_secure_instruction(cpu, run);
>> + break;
>> case ICPT_INSTRUCTION:
>> r = handle_instruction(cpu, run);
>> break;
>>
>
> Thomas
>
>
--
Pierre Morel
IBM Lab Boeblingen
next prev parent reply other threads:[~2019-11-28 13:08 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-28 10:13 [PATCH v1 0/1] s390x: protvirt: SCLP interpretation Pierre Morel
2019-11-28 10:13 ` [PATCH v1 1/1] " Pierre Morel
2019-11-28 12:10 ` Thomas Huth
2019-11-28 13:05 ` Pierre Morel [this message]
2019-11-28 12:28 ` [PATCH v1 0/1] " Janosch Frank
2019-11-28 13:15 ` Pierre Morel
2019-11-28 23:09 ` no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=77551bc9-d81c-4c56-e754-84ad44b8e2bd@linux.ibm.com \
--to=pmorel@linux.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).