aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-01-01 10:23:29 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-22 07:24:37 -0400
commitd95fb12ff4d73e897126043bb5d03a068997a2ef (patch)
treee8b5b34cb7810fa7bb8f7ae3edcb2f3d7ea404da
parent1b0462e574f5238bb1ee811f014d629092c160cb (diff)
KVM: s390: add lowcore access functions
put_guest_lc, read_guest_lc and write_guest_lc are guest access functions which shall only be used to access the lowcore of a vcpu. These functions should be used for e.g. interrupt handlers where no guest memory access protection facilities, like key or low address protection, are applicable. At a later point guest vcpu lowcore access should happen via pinned prefix pages, so that these pages can be accessed directly via the kernel mapping. All of these *_lc functions can be removed then. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/kvm/gaccess.h95
1 files changed, 93 insertions, 2 deletions
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index ae3cb638f220..917aeaa04fff 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * access guest memory 2 * access guest memory
3 * 3 *
4 * Copyright IBM Corp. 2008, 2009 4 * Copyright IBM Corp. 2008, 2014
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -15,7 +15,8 @@
15 15
16#include <linux/compiler.h> 16#include <linux/compiler.h>
17#include <linux/kvm_host.h> 17#include <linux/kvm_host.h>
18#include <asm/uaccess.h> 18#include <linux/uaccess.h>
19#include <linux/ptrace.h>
19#include "kvm-s390.h" 20#include "kvm-s390.h"
20 21
21/* Convert real to absolute address by applying the prefix of the CPU */ 22/* Convert real to absolute address by applying the prefix of the CPU */
@@ -136,4 +137,94 @@ static inline int __copy_guest(struct kvm_vcpu *vcpu, unsigned long to,
136#define copy_from_guest_absolute(vcpu, to, from, size) \ 137#define copy_from_guest_absolute(vcpu, to, from, size) \
137 __copy_guest(vcpu, (unsigned long)to, from, size, 0, 0) 138 __copy_guest(vcpu, (unsigned long)to, from, size, 0, 0)
138 139
140/*
141 * put_guest_lc, read_guest_lc and write_guest_lc are guest access functions
142 * which shall only be used to access the lowcore of a vcpu.
143 * These functions should be used for e.g. interrupt handlers where no
144 * guest memory access protection facilities, like key or low address
145 * protection, are applicable.
146 * At a later point guest vcpu lowcore access should happen via pinned
147 * prefix pages, so that these pages can be accessed directly via the
148 * kernel mapping. All of these *_lc functions can be removed then.
149 */
150
151/**
152 * put_guest_lc - write a simple variable to a guest vcpu's lowcore
153 * @vcpu: virtual cpu
154 * @x: value to copy to guest
155 * @gra: vcpu's destination guest real address
156 *
157 * Copies a simple value from kernel space to a guest vcpu's lowcore.
158 * The size of the variable may be 1, 2, 4 or 8 bytes. The destination
159 * must be located in the vcpu's lowcore. Otherwise the result is undefined.
160 *
161 * Returns zero on success or -EFAULT on error.
162 *
163 * Note: an error indicates that either the kernel is out of memory or
164 * the guest memory mapping is broken. In any case the best solution
165 * would be to terminate the guest.
166 * It is wrong to inject a guest exception.
167 */
168#define put_guest_lc(vcpu, x, gra) \
169({ \
170 struct kvm_vcpu *__vcpu = (vcpu); \
171 __typeof__(*(gra)) __x = (x); \
172 unsigned long __gpa; \
173 \
174 __gpa = (unsigned long)(gra); \
175 __gpa += __vcpu->arch.sie_block->prefix; \
176 kvm_write_guest(__vcpu->kvm, __gpa, &__x, sizeof(__x)); \
177})
178
179/**
180 * write_guest_lc - copy data from kernel space to guest vcpu's lowcore
181 * @vcpu: virtual cpu
182 * @gra: vcpu's source guest real address
183 * @data: source address in kernel space
184 * @len: number of bytes to copy
185 *
186 * Copy data from kernel space to guest vcpu's lowcore. The entire range must
187 * be located within the vcpu's lowcore, otherwise the result is undefined.
188 *
189 * Returns zero on success or -EFAULT on error.
190 *
191 * Note: an error indicates that either the kernel is out of memory or
192 * the guest memory mapping is broken. In any case the best solution
193 * would be to terminate the guest.
194 * It is wrong to inject a guest exception.
195 */
196static inline __must_check
197int write_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
198 unsigned long len)
199{
200 unsigned long gpa = gra + vcpu->arch.sie_block->prefix;
201
202 return kvm_write_guest(vcpu->kvm, gpa, data, len);
203}
204
205/**
206 * read_guest_lc - copy data from guest vcpu's lowcore to kernel space
207 * @vcpu: virtual cpu
208 * @gra: vcpu's source guest real address
209 * @data: destination address in kernel space
210 * @len: number of bytes to copy
211 *
212 * Copy data from guest vcpu's lowcore to kernel space. The entire range must
213 * be located within the vcpu's lowcore, otherwise the result is undefined.
214 *
215 * Returns zero on success or -EFAULT on error.
216 *
217 * Note: an error indicates that either the kernel is out of memory or
218 * the guest memory mapping is broken. In any case the best solution
219 * would be to terminate the guest.
220 * It is wrong to inject a guest exception.
221 */
222static inline __must_check
223int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
224 unsigned long len)
225{
226 unsigned long gpa = gra + vcpu->arch.sie_block->prefix;
227
228 return kvm_read_guest(vcpu->kvm, gpa, data, len);
229}
139#endif /* __KVM_S390_GACCESS_H */ 230#endif /* __KVM_S390_GACCESS_H */