Commit 1644e270 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-s390-next-5.19-1' of...

Merge tag 'kvm-s390-next-5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD

KVM: s390: Fix and feature for 5.19

- ultravisor communication device driver
- fix TEID on terminating storage key ops
parents b699da3d c7115964
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3814,12 +3814,18 @@ in case of KVM_S390_MEMOP_F_CHECK_ONLY), the ioctl returns a positive
error number indicating the type of exception. This exception is also
raised directly at the corresponding VCPU if the flag
KVM_S390_MEMOP_F_INJECT_EXCEPTION is set.
On protection exceptions, unless specified otherwise, the injected
translation-exception identifier (TEID) indicates suppression.

If the KVM_S390_MEMOP_F_SKEY_PROTECTION flag is set, storage key
protection is also in effect and may cause exceptions if accesses are
prohibited given the access key designated by "key"; the valid range is 0..15.
KVM_S390_MEMOP_F_SKEY_PROTECTION is available if KVM_CAP_S390_MEM_OP_EXTENSION
is > 0.
Since the accessed memory may span multiple pages and those pages might have
different storage keys, it is possible that a protection exception occurs
after memory has been modified. In this case, if the exception is injected,
the TEID does not indicate suppression.

Absolute read/write:
^^^^^^^^^^^^^^^^^^^^
+3 −0
Original line number Diff line number Diff line
@@ -10785,9 +10785,12 @@ F: Documentation/virt/kvm/s390*
F:	arch/s390/include/asm/gmap.h
F:	arch/s390/include/asm/kvm*
F:	arch/s390/include/uapi/asm/kvm*
F:	arch/s390/include/uapi/asm/uvdevice.h
F:	arch/s390/kernel/uv.c
F:	arch/s390/kvm/
F:	arch/s390/mm/gmap.c
F:	drivers/s390/char/uvdevice.c
F:	tools/testing/selftests/drivers/s390x/uvdevice/
F:	tools/testing/selftests/kvm/*/s390x/
F:	tools/testing/selftests/kvm/s390x/
+22 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * Ultravisor Interfaces
 *
 * Copyright IBM Corp. 2019
 * Copyright IBM Corp. 2019, 2022
 *
 * Author(s):
 *	Vasily Gorbik <gor@linux.ibm.com>
@@ -52,6 +52,7 @@
#define UVC_CMD_UNPIN_PAGE_SHARED	0x0342
#define UVC_CMD_SET_SHARED_ACCESS	0x1000
#define UVC_CMD_REMOVE_SHARED_ACCESS	0x1001
#define UVC_CMD_RETR_ATTEST		0x1020

/* Bits in installed uv calls */
enum uv_cmds_inst {
@@ -76,6 +77,7 @@ enum uv_cmds_inst {
	BIT_UVC_CMD_UNSHARE_ALL = 20,
	BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
	BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
	BIT_UVC_CMD_RETR_ATTEST = 28,
};

enum uv_feat_ind {
@@ -219,6 +221,25 @@ struct uv_cb_share {
	u64 reserved28;
} __packed __aligned(8);

/* Retrieve Attestation Measurement */
struct uv_cb_attest {
	struct uv_cb_header header;	/* 0x0000 */
	u64 reserved08[2];		/* 0x0008 */
	u64 arcb_addr;			/* 0x0018 */
	u64 cont_token;			/* 0x0020 */
	u8  reserved28[6];		/* 0x0028 */
	u16 user_data_len;		/* 0x002e */
	u8  user_data[256];		/* 0x0030 */
	u32 reserved130[3];		/* 0x0130 */
	u32 meas_len;			/* 0x013c */
	u64 meas_addr;			/* 0x0140 */
	u8  config_uid[16];		/* 0x0148 */
	u32 reserved158;		/* 0x0158 */
	u32 add_data_len;		/* 0x015c */
	u64 add_data_addr;		/* 0x0160 */
	u64 reserved168[4];		/* 0x0168 */
} __packed __aligned(8);

static inline int __uv_call(unsigned long r1, unsigned long r2)
{
	int cc;
+51 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 *  Copyright IBM Corp. 2022
 *  Author(s): Steffen Eiden <seiden@linux.ibm.com>
 */
#ifndef __S390_ASM_UVDEVICE_H
#define __S390_ASM_UVDEVICE_H

#include <linux/types.h>

struct uvio_ioctl_cb {
	__u32 flags;
	__u16 uv_rc;			/* UV header rc value */
	__u16 uv_rrc;			/* UV header rrc value */
	__u64 argument_addr;		/* Userspace address of uvio argument */
	__u32 argument_len;
	__u8  reserved14[0x40 - 0x14];	/* must be zero */
};

#define UVIO_ATT_USER_DATA_LEN		0x100
#define UVIO_ATT_UID_LEN		0x10
struct uvio_attest {
	__u64 arcb_addr;				/* 0x0000 */
	__u64 meas_addr;				/* 0x0008 */
	__u64 add_data_addr;				/* 0x0010 */
	__u8  user_data[UVIO_ATT_USER_DATA_LEN];	/* 0x0018 */
	__u8  config_uid[UVIO_ATT_UID_LEN];		/* 0x0118 */
	__u32 arcb_len;					/* 0x0128 */
	__u32 meas_len;					/* 0x012c */
	__u32 add_data_len;				/* 0x0130 */
	__u16 user_data_len;				/* 0x0134 */
	__u16 reserved136;				/* 0x0136 */
};

/*
 * The following max values define an upper length for the IOCTL in/out buffers.
 * However, they do not represent the maximum the Ultravisor allows which is
 * often way smaller. By allowing larger buffer sizes we hopefully do not need
 * to update the code with every machine update. It is therefore possible for
 * userspace to request more memory than actually used by kernel/UV.
 */
#define UVIO_ATT_ARCB_MAX_LEN		0x100000
#define UVIO_ATT_MEASUREMENT_MAX_LEN	0x8000
#define UVIO_ATT_ADDITIONAL_MAX_LEN	0x8000

#define UVIO_DEVICE_NAME "uv"
#define UVIO_TYPE_UVC 'u'

#define UVIO_IOCTL_ATT _IOWR(UVIO_TYPE_UVC, 0x01, struct uvio_ioctl_cb)

#endif /* __S390_ASM_UVDEVICE_H */
+18 −4
Original line number Diff line number Diff line
@@ -491,8 +491,8 @@ enum prot_type {
	PROT_TYPE_IEP  = 4,
};

static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva,
		     u8 ar, enum gacc_mode mode, enum prot_type prot)
static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
			    enum gacc_mode mode, enum prot_type prot, bool terminate)
{
	struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
	struct trans_exc_code_bits *tec;
@@ -520,6 +520,11 @@ static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva,
			tec->b61 = 1;
			break;
		}
		if (terminate) {
			tec->b56 = 0;
			tec->b60 = 0;
			tec->b61 = 0;
		}
		fallthrough;
	case PGM_ASCE_TYPE:
	case PGM_PAGE_TRANSLATION:
@@ -552,6 +557,12 @@ static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva,
	return code;
}

static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
		     enum gacc_mode mode, enum prot_type prot)
{
	return trans_exc_ending(vcpu, code, gva, ar, mode, prot, false);
}

static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
			 unsigned long ga, u8 ar, enum gacc_mode mode)
{
@@ -1109,8 +1120,11 @@ int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
		data += fragment_len;
		ga = kvm_s390_logical_to_effective(vcpu, ga + fragment_len);
	}
	if (rc > 0)
		rc = trans_exc(vcpu, rc, ga, ar, mode, prot);
	if (rc > 0) {
		bool terminate = (mode == GACC_STORE) && (idx > 0);

		rc = trans_exc_ending(vcpu, rc, ga, ar, mode, prot, terminate);
	}
out_unlock:
	if (need_ipte_lock)
		ipte_unlock(vcpu);
Loading