On 24.10.19 13:40, Janosch Frank wrote:
Guest registers for protected guests are stored at offset 0x380.
Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx>
---
arch/s390/include/asm/kvm_host.h | 4 +++-
arch/s390/kvm/kvm-s390.c | 11 +++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 0ab309b7bf4c..5deabf9734d9 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -336,7 +336,9 @@ struct kvm_s390_itdb {
struct sie_page {
struct kvm_s390_sie_block sie_block;
struct mcck_volatile_info mcck_info; /* 0x0200 */
- __u8 reserved218[1000]; /* 0x0218 */
+ __u8 reserved218[360]; /* 0x0218 */
+ __u64 pv_grregs[16]; /* 0x380 */
+ __u8 reserved400[512];
struct kvm_s390_itdb itdb; /* 0x0600 */
__u8 reserved700[2304]; /* 0x0700 */
};
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 490fde080107..97d3a81e5074 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -3965,6 +3965,7 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
static int __vcpu_run(struct kvm_vcpu *vcpu)
{
int rc, exit_reason;
+ struct sie_page *sie_page = (struct sie_page *)vcpu->arch.sie_block;
/*
* We try to hold kvm->srcu during most of vcpu_run (except when run-
@@ -3986,8 +3987,18 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
guest_enter_irqoff();
__disable_cpu_timer_accounting(vcpu);
local_irq_enable();
+ if (kvm_s390_pv_is_protected(vcpu->kvm)) {
+ memcpy(sie_page->pv_grregs,
+ vcpu->run->s.regs.gprs,
+ sizeof(sie_page->pv_grregs));
+ }
exit_reason = sie64a(vcpu->arch.sie_block,
vcpu->run->s.regs.gprs);
+ if (kvm_s390_pv_is_protected(vcpu->kvm)) {
+ memcpy(vcpu->run->s.regs.gprs,
+ sie_page->pv_grregs,
+ sizeof(sie_page->pv_grregs));
+ }
sie64a will load/save gprs 0-13 from to vcpu->run->s.regs.gprs.
I would have assume that this is not required for prot virt, because the
HW has direct access via the sie block?
1. Would it make sense to have a specialized sie64a() (or a parameter,
e.g., if you pass in NULL in r3), that optimizes this loading/saving?
Eventually we can also optimize which host registers to save/restore then.
2. Avoid this copying here. We have to store the state to
vcpu->run->s.regs.gprs when returning to user space and restore the
state when coming from user space.
Also, we access the GPRS from interception handlers, there we might use
wrappers like
kvm_s390_set_gprs()
kvm_s390_get_gprs()
to route to the right location. There are multiple options to optimize this.
--
Thanks,
David / dhildenb