Commit 69fd3876 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

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

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

- PV crypto passthrough enablement (Tony, Steffen, Viktor, Janosch)
  Allows a PV guest to use crypto cards. Card access is governed by
  the firmware and once a crypto queue is "bound" to a PV VM every
  other entity (PV or not) looses access until it is not bound
  anymore. Enablement is done via flags when creating the PV VM.

- Guest debug fixes (Ilya)
parents 1814db83 899e2206
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -817,6 +817,8 @@ struct kvm_s390_cpu_model {
	__u64 *fac_list;
	u64 cpuid;
	unsigned short ibc;
	/* subset of available UV-features for pv-guests enabled by user space */
	struct kvm_s390_vm_cpu_uv_feat uv_feat_guest;
};

typedef int (*crypto_hook)(struct kvm_vcpu *vcpu);
@@ -1028,6 +1030,9 @@ static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa)

extern char sie_exit;

bool kvm_s390_pv_is_protected(struct kvm *kvm);
bool kvm_s390_pv_cpu_is_protected(struct kvm_vcpu *vcpu);

extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc);
extern int kvm_s390_gisc_unregister(struct kvm *kvm, u32 gisc);

+24 −1
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ enum uv_cmds_inst {
enum uv_feat_ind {
	BIT_UV_FEAT_MISC = 0,
	BIT_UV_FEAT_AIV = 1,
	BIT_UV_FEAT_AP = 4,
	BIT_UV_FEAT_AP_INTR = 5,
};

struct uv_cb_header {
@@ -159,7 +161,15 @@ struct uv_cb_cgc {
	u64 guest_handle;
	u64 conf_base_stor_origin;
	u64 conf_virt_stor_origin;
	u64 reserved30;
	u8  reserved30[6];
	union {
		struct {
			u16 : 14;
			u16 ap_instr_intr : 1;
			u16 ap_allow_instr : 1;
		};
		u16 raw;
	} flags;
	u64 guest_stor_origin;
	u64 guest_stor_len;
	u64 guest_sca;
@@ -397,6 +407,13 @@ struct uv_info {

extern struct uv_info uv_info;

static inline bool uv_has_feature(u8 feature_bit)
{
	if (feature_bit >= sizeof(uv_info.uv_feature_indications) * 8)
		return false;
	return test_bit_inv(feature_bit, &uv_info.uv_feature_indications);
}

#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
extern int prot_virt_guest;

@@ -463,6 +480,7 @@ static inline int is_prot_virt_host(void)
	return prot_virt_host;
}

int uv_pin_shared(unsigned long paddr);
int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
int uv_destroy_owned_page(unsigned long paddr);
@@ -475,6 +493,11 @@ void setup_uv(void);
#define is_prot_virt_host() 0
static inline void setup_uv(void) {}

static inline int uv_pin_shared(unsigned long paddr)
{
	return 0;
}

static inline int uv_destroy_owned_page(unsigned long paddr)
{
	return 0;
+16 −0
Original line number Diff line number Diff line
@@ -159,6 +159,22 @@ struct kvm_s390_vm_cpu_subfunc {
	__u8 reserved[1728];
};

#define KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST	6
#define KVM_S390_VM_CPU_MACHINE_UV_FEAT_GUEST	7

#define KVM_S390_VM_CPU_UV_FEAT_NR_BITS	64
struct kvm_s390_vm_cpu_uv_feat {
	union {
		struct {
			__u64 : 4;
			__u64 ap : 1;		/* bit 4 */
			__u64 ap_intr : 1;	/* bit 5 */
			__u64 : 58;
		};
		__u64 feat;
	};
};

/* kvm attributes for crypto */
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW	0
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW	1
+3 −2
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ void __init setup_uv(void)
 * Requests the Ultravisor to pin the page in the shared state. This will
 * cause an intercept when the guest attempts to unshare the pinned page.
 */
static int uv_pin_shared(unsigned long paddr)
int uv_pin_shared(unsigned long paddr)
{
	struct uv_cb_cfs uvcb = {
		.header.cmd = UVC_CMD_PIN_PAGE_SHARED,
@@ -100,6 +100,7 @@ static int uv_pin_shared(unsigned long paddr)
		return -EINVAL;
	return 0;
}
EXPORT_SYMBOL_GPL(uv_pin_shared);

/*
 * Requests the Ultravisor to destroy a guest page and make it
@@ -257,7 +258,7 @@ static bool should_export_before_import(struct uv_cb_header *uvcb, struct mm_str
	 * shared page from a different protected VM will automatically also
	 * transfer its ownership.
	 */
	if (test_bit_inv(BIT_UV_FEAT_MISC, &uv_info.uv_feature_indications))
	if (uv_has_feature(BIT_UV_FEAT_MISC))
		return false;
	if (uvcb->cmd == UVC_CMD_UNPIN_PAGE_SHARED)
		return false;
+32 −6
Original line number Diff line number Diff line
@@ -228,6 +228,21 @@ static int handle_itdb(struct kvm_vcpu *vcpu)

#define per_event(vcpu) (vcpu->arch.sie_block->iprcc & PGM_PER)

static bool should_handle_per_event(const struct kvm_vcpu *vcpu)
{
	if (!guestdbg_enabled(vcpu) || !per_event(vcpu))
		return false;
	if (guestdbg_sstep_enabled(vcpu) &&
	    vcpu->arch.sie_block->iprcc != PGM_PER) {
		/*
		 * __vcpu_run() will exit after delivering the concurrently
		 * indicated condition.
		 */
		return false;
	}
	return true;
}

static int handle_prog(struct kvm_vcpu *vcpu)
{
	psw_t psw;
@@ -242,7 +257,7 @@ static int handle_prog(struct kvm_vcpu *vcpu)
	if (kvm_s390_pv_cpu_is_protected(vcpu))
		return -EOPNOTSUPP;

	if (guestdbg_enabled(vcpu) && per_event(vcpu)) {
	if (should_handle_per_event(vcpu)) {
		rc = kvm_s390_handle_per_event(vcpu);
		if (rc)
			return rc;
@@ -571,6 +586,19 @@ static int handle_pv_notification(struct kvm_vcpu *vcpu)
	return handle_instruction(vcpu);
}

static bool should_handle_per_ifetch(const struct kvm_vcpu *vcpu, int rc)
{
	/* Process PER, also if the instruction is processed in user space. */
	if (!(vcpu->arch.sie_block->icptstatus & 0x02))
		return false;
	if (rc != 0 && rc != -EOPNOTSUPP)
		return false;
	if (guestdbg_sstep_enabled(vcpu) && vcpu->arch.local_int.pending_irqs)
		/* __vcpu_run() will exit after delivering the interrupt. */
		return false;
	return true;
}

int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
{
	int rc, per_rc = 0;
@@ -605,8 +633,8 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
		rc = handle_partial_execution(vcpu);
		break;
	case ICPT_KSS:
		rc = kvm_s390_skey_check_enable(vcpu);
		break;
		/* Instruction will be redriven, skip the PER check. */
		return kvm_s390_skey_check_enable(vcpu);
	case ICPT_MCHKREQ:
	case ICPT_INT_ENABLE:
		/*
@@ -633,9 +661,7 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
		return -EOPNOTSUPP;
	}

	/* process PER, also if the instruction is processed in user space */
	if (vcpu->arch.sie_block->icptstatus & 0x02 &&
	    (!rc || rc == -EOPNOTSUPP))
	if (should_handle_per_ifetch(vcpu, rc))
		per_rc = kvm_s390_handle_per_ifetch_icpt(vcpu);
	return per_rc ? per_rc : rc;
}
Loading