linux/arch/s390/kvm/gaccess.h
<<
>>
Prefs
   1/*
   2 * access guest memory
   3 *
   4 * Copyright IBM Corp. 2008, 2014
   5 *
   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)
   8 * as published by the Free Software Foundation.
   9 *
  10 *    Author(s): Carsten Otte <cotte@de.ibm.com>
  11 */
  12
  13#ifndef __KVM_S390_GACCESS_H
  14#define __KVM_S390_GACCESS_H
  15
  16#include <linux/compiler.h>
  17#include <linux/kvm_host.h>
  18#include <linux/uaccess.h>
  19#include <linux/ptrace.h>
  20#include "kvm-s390.h"
  21
  22/**
  23 * kvm_s390_real_to_abs - convert guest real address to guest absolute address
  24 * @vcpu - guest virtual cpu
  25 * @gra - guest real address
  26 *
  27 * Returns the guest absolute address that corresponds to the passed guest real
  28 * address @gra of a virtual guest cpu by applying its prefix.
  29 */
  30static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu,
  31                                                 unsigned long gra)
  32{
  33        unsigned long prefix  = kvm_s390_get_prefix(vcpu);
  34
  35        if (gra < 2 * PAGE_SIZE)
  36                gra += prefix;
  37        else if (gra >= prefix && gra < prefix + 2 * PAGE_SIZE)
  38                gra -= prefix;
  39        return gra;
  40}
  41
  42/**
  43 * kvm_s390_logical_to_effective - convert guest logical to effective address
  44 * @vcpu: guest virtual cpu
  45 * @ga: guest logical address
  46 *
  47 * Convert a guest vcpu logical address to a guest vcpu effective address by
  48 * applying the rules of the vcpu's addressing mode defined by PSW bits 31
  49 * and 32 (extendended/basic addressing mode).
  50 *
  51 * Depending on the vcpu's addressing mode the upper 40 bits (24 bit addressing
  52 * mode), 33 bits (31 bit addressing mode) or no bits (64 bit addressing mode)
  53 * of @ga will be zeroed and the remaining bits will be returned.
  54 */
  55static inline unsigned long kvm_s390_logical_to_effective(struct kvm_vcpu *vcpu,
  56                                                          unsigned long ga)
  57{
  58        psw_t *psw = &vcpu->arch.sie_block->gpsw;
  59
  60        if (psw_bits(*psw).eaba == PSW_AMODE_64BIT)
  61                return ga;
  62        if (psw_bits(*psw).eaba == PSW_AMODE_31BIT)
  63                return ga & ((1UL << 31) - 1);
  64        return ga & ((1UL << 24) - 1);
  65}
  66
  67/*
  68 * put_guest_lc, read_guest_lc and write_guest_lc are guest access functions
  69 * which shall only be used to access the lowcore of a vcpu.
  70 * These functions should be used for e.g. interrupt handlers where no
  71 * guest memory access protection facilities, like key or low address
  72 * protection, are applicable.
  73 * At a later point guest vcpu lowcore access should happen via pinned
  74 * prefix pages, so that these pages can be accessed directly via the
  75 * kernel mapping. All of these *_lc functions can be removed then.
  76 */
  77
  78/**
  79 * put_guest_lc - write a simple variable to a guest vcpu's lowcore
  80 * @vcpu: virtual cpu
  81 * @x: value to copy to guest
  82 * @gra: vcpu's destination guest real address
  83 *
  84 * Copies a simple value from kernel space to a guest vcpu's lowcore.
  85 * The size of the variable may be 1, 2, 4 or 8 bytes. The destination
  86 * must be located in the vcpu's lowcore. Otherwise the result is undefined.
  87 *
  88 * Returns zero on success or -EFAULT on error.
  89 *
  90 * Note: an error indicates that either the kernel is out of memory or
  91 *       the guest memory mapping is broken. In any case the best solution
  92 *       would be to terminate the guest.
  93 *       It is wrong to inject a guest exception.
  94 */
  95#define put_guest_lc(vcpu, x, gra)                              \
  96({                                                              \
  97        struct kvm_vcpu *__vcpu = (vcpu);                       \
  98        __typeof__(*(gra)) __x = (x);                           \
  99        unsigned long __gpa;                                    \
 100                                                                \
 101        __gpa = (unsigned long)(gra);                           \
 102        __gpa += kvm_s390_get_prefix(__vcpu);                   \
 103        kvm_write_guest(__vcpu->kvm, __gpa, &__x, sizeof(__x)); \
 104})
 105
 106/**
 107 * write_guest_lc - copy data from kernel space to guest vcpu's lowcore
 108 * @vcpu: virtual cpu
 109 * @gra: vcpu's source guest real address
 110 * @data: source address in kernel space
 111 * @len: number of bytes to copy
 112 *
 113 * Copy data from kernel space to guest vcpu's lowcore. The entire range must
 114 * be located within the vcpu's lowcore, otherwise the result is undefined.
 115 *
 116 * Returns zero on success or -EFAULT on error.
 117 *
 118 * Note: an error indicates that either the kernel is out of memory or
 119 *       the guest memory mapping is broken. In any case the best solution
 120 *       would be to terminate the guest.
 121 *       It is wrong to inject a guest exception.
 122 */
 123static inline __must_check
 124int write_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
 125                   unsigned long len)
 126{
 127        unsigned long gpa = gra + kvm_s390_get_prefix(vcpu);
 128
 129        return kvm_write_guest(vcpu->kvm, gpa, data, len);
 130}
 131
 132/**
 133 * read_guest_lc - copy data from guest vcpu's lowcore to kernel space
 134 * @vcpu: virtual cpu
 135 * @gra: vcpu's source guest real address
 136 * @data: destination address in kernel space
 137 * @len: number of bytes to copy
 138 *
 139 * Copy data from guest vcpu's lowcore to kernel space. The entire range must
 140 * be located within the vcpu's lowcore, otherwise the result is undefined.
 141 *
 142 * Returns zero on success or -EFAULT on error.
 143 *
 144 * Note: an error indicates that either the kernel is out of memory or
 145 *       the guest memory mapping is broken. In any case the best solution
 146 *       would be to terminate the guest.
 147 *       It is wrong to inject a guest exception.
 148 */
 149static inline __must_check
 150int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
 151                  unsigned long len)
 152{
 153        unsigned long gpa = gra + kvm_s390_get_prefix(vcpu);
 154
 155        return kvm_read_guest(vcpu->kvm, gpa, data, len);
 156}
 157
 158int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
 159                            ar_t ar, unsigned long *gpa, int write);
 160int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
 161                    unsigned long length, int is_write);
 162
 163int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
 164                 unsigned long len, int write);
 165
 166int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
 167                      void *data, unsigned long len, int write);
 168
 169/**
 170 * write_guest - copy data from kernel space to guest space
 171 * @vcpu: virtual cpu
 172 * @ga: guest address
 173 * @ar: access register
 174 * @data: source address in kernel space
 175 * @len: number of bytes to copy
 176 *
 177 * Copy @len bytes from @data (kernel space) to @ga (guest address).
 178 * In order to copy data to guest space the PSW of the vcpu is inspected:
 179 * If DAT is off data will be copied to guest real or absolute memory.
 180 * If DAT is on data will be copied to the address space as specified by
 181 * the address space bits of the PSW:
 182 * Primary, secondary, home space or access register mode.
 183 * The addressing mode of the PSW is also inspected, so that address wrap
 184 * around is taken into account for 24-, 31- and 64-bit addressing mode,
 185 * if the to be copied data crosses page boundaries in guest address space.
 186 * In addition also low address and DAT protection are inspected before
 187 * copying any data (key protection is currently not implemented).
 188 *
 189 * This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu.
 190 * In case of an access exception (e.g. protection exception) pgm will contain
 191 * all data necessary so that a subsequent call to 'kvm_s390_inject_prog_vcpu()'
 192 * will inject a correct exception into the guest.
 193 * If no access exception happened, the contents of pgm are undefined when
 194 * this function returns.
 195 *
 196 * Returns:  - zero on success
 197 *           - a negative value if e.g. the guest mapping is broken or in
 198 *             case of out-of-memory. In this case the contents of pgm are
 199 *             undefined. Also parts of @data may have been copied to guest
 200 *             space.
 201 *           - a positive value if an access exception happened. In this case
 202 *             the returned value is the program interruption code and the
 203 *             contents of pgm may be used to inject an exception into the
 204 *             guest. No data has been copied to guest space.
 205 *
 206 * Note: in case an access exception is recognized no data has been copied to
 207 *       guest space (this is also true, if the to be copied data would cross
 208 *       one or more page boundaries in guest space).
 209 *       Therefore this function may be used for nullifying and suppressing
 210 *       instruction emulation.
 211 *       It may also be used for terminating instructions, if it is undefined
 212 *       if data has been changed in guest space in case of an exception.
 213 */
 214static inline __must_check
 215int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
 216                unsigned long len)
 217{
 218        return access_guest(vcpu, ga, ar, data, len, 1);
 219}
 220
 221/**
 222 * read_guest - copy data from guest space to kernel space
 223 * @vcpu: virtual cpu
 224 * @ga: guest address
 225 * @ar: access register
 226 * @data: destination address in kernel space
 227 * @len: number of bytes to copy
 228 *
 229 * Copy @len bytes from @ga (guest address) to @data (kernel space).
 230 *
 231 * The behaviour of read_guest is identical to write_guest, except that
 232 * data will be copied from guest space to kernel space.
 233 */
 234static inline __must_check
 235int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
 236               unsigned long len)
 237{
 238        return access_guest(vcpu, ga, ar, data, len, 0);
 239}
 240
 241/**
 242 * write_guest_abs - copy data from kernel space to guest space absolute
 243 * @vcpu: virtual cpu
 244 * @gpa: guest physical (absolute) address
 245 * @data: source address in kernel space
 246 * @len: number of bytes to copy
 247 *
 248 * Copy @len bytes from @data (kernel space) to @gpa (guest absolute address).
 249 * It is up to the caller to ensure that the entire guest memory range is
 250 * valid memory before calling this function.
 251 * Guest low address and key protection are not checked.
 252 *
 253 * Returns zero on success or -EFAULT on error.
 254 *
 255 * If an error occurs data may have been copied partially to guest memory.
 256 */
 257static inline __must_check
 258int write_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
 259                    unsigned long len)
 260{
 261        return kvm_write_guest(vcpu->kvm, gpa, data, len);
 262}
 263
 264/**
 265 * read_guest_abs - copy data from guest space absolute to kernel space
 266 * @vcpu: virtual cpu
 267 * @gpa: guest physical (absolute) address
 268 * @data: destination address in kernel space
 269 * @len: number of bytes to copy
 270 *
 271 * Copy @len bytes from @gpa (guest absolute address) to @data (kernel space).
 272 * It is up to the caller to ensure that the entire guest memory range is
 273 * valid memory before calling this function.
 274 * Guest key protection is not checked.
 275 *
 276 * Returns zero on success or -EFAULT on error.
 277 *
 278 * If an error occurs data may have been copied partially to kernel space.
 279 */
 280static inline __must_check
 281int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
 282                   unsigned long len)
 283{
 284        return kvm_read_guest(vcpu->kvm, gpa, data, len);
 285}
 286
 287/**
 288 * write_guest_real - copy data from kernel space to guest space real
 289 * @vcpu: virtual cpu
 290 * @gra: guest real address
 291 * @data: source address in kernel space
 292 * @len: number of bytes to copy
 293 *
 294 * Copy @len bytes from @data (kernel space) to @gra (guest real address).
 295 * It is up to the caller to ensure that the entire guest memory range is
 296 * valid memory before calling this function.
 297 * Guest low address and key protection are not checked.
 298 *
 299 * Returns zero on success or -EFAULT on error.
 300 *
 301 * If an error occurs data may have been copied partially to guest memory.
 302 */
 303static inline __must_check
 304int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
 305                     unsigned long len)
 306{
 307        return access_guest_real(vcpu, gra, data, len, 1);
 308}
 309
 310/**
 311 * read_guest_real - copy data from guest space real to kernel space
 312 * @vcpu: virtual cpu
 313 * @gra: guest real address
 314 * @data: destination address in kernel space
 315 * @len: number of bytes to copy
 316 *
 317 * Copy @len bytes from @gra (guest real address) to @data (kernel space).
 318 * It is up to the caller to ensure that the entire guest memory range is
 319 * valid memory before calling this function.
 320 * Guest key protection is not checked.
 321 *
 322 * Returns zero on success or -EFAULT on error.
 323 *
 324 * If an error occurs data may have been copied partially to kernel space.
 325 */
 326static inline __must_check
 327int read_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
 328                    unsigned long len)
 329{
 330        return access_guest_real(vcpu, gra, data, len, 0);
 331}
 332
 333void ipte_lock(struct kvm_vcpu *vcpu);
 334void ipte_unlock(struct kvm_vcpu *vcpu);
 335int ipte_lock_held(struct kvm_vcpu *vcpu);
 336int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra);
 337
 338#endif /* __KVM_S390_GACCESS_H */
 339