Commit 356dab4e authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

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

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

* New ucontrol selftest
* Inline assembly touchups
parents 0cdcc99e f9b56b2c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ CONFIG_CMM=m
CONFIG_APPLDATA_BASE=y
CONFIG_S390_HYPFS_FS=y
CONFIG_KVM=m
CONFIG_KVM_S390_UCONTROL=y
CONFIG_S390_UNWIND_SELFTEST=m
CONFIG_S390_KPROBES_SANITY_TEST=m
CONFIG_S390_MODULES_SANITY_TEST=m
+18 −9
Original line number Diff line number Diff line
@@ -348,20 +348,29 @@ static inline int plo_test_bit(unsigned char nr)
	return cc == 0;
}

static __always_inline void __insn32_query(unsigned int opcode, u8 *query)
static __always_inline void __sortl_query(u8 (*query)[32])
{
	asm volatile(
		"	lghi	0,0\n"
		"	lgr	1,%[query]\n"
		"	la	1,%[query]\n"
		/* Parameter registers are ignored */
		"	.insn	rrf,%[opc] << 16,2,4,6,0\n"
		"	.insn	rre,0xb9380000,2,4\n"
		: [query] "=R" (*query)
		:
		: [query] "d" ((unsigned long)query), [opc] "i" (opcode)
		: "cc", "memory", "0", "1");
		: "cc", "0", "1");
}

#define INSN_SORTL 0xb938
#define INSN_DFLTCC 0xb939
static __always_inline void __dfltcc_query(u8 (*query)[32])
{
	asm volatile(
		"	lghi	0,0\n"
		"	la	1,%[query]\n"
		/* Parameter registers are ignored */
		"	.insn	rrf,0xb9390000,2,4,6,0\n"
		: [query] "=R" (*query)
		:
		: "cc", "0", "1");
}

static void __init kvm_s390_cpu_feat_init(void)
{
@@ -415,10 +424,10 @@ static void __init kvm_s390_cpu_feat_init(void)
			      kvm_s390_available_subfunc.kdsa);

	if (test_facility(150)) /* SORTL */
		__insn32_query(INSN_SORTL, kvm_s390_available_subfunc.sortl);
		__sortl_query(&kvm_s390_available_subfunc.sortl);

	if (test_facility(151)) /* DFLTCC */
		__insn32_query(INSN_DFLTCC, kvm_s390_available_subfunc.dfltcc);
		__dfltcc_query(&kvm_s390_available_subfunc.dfltcc);

	if (MACHINE_HAS_ESOP)
		allow_cpu_feat(KVM_S390_VM_CPU_FEAT_ESOP);
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@
!*.h
!*.S
!*.sh
!config
+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ TEST_GEN_PROGS_s390x += s390x/tprot
TEST_GEN_PROGS_s390x += s390x/cmma_test
TEST_GEN_PROGS_s390x += s390x/debug_test
TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
TEST_GEN_PROGS_s390x += s390x/ucontrol_test
TEST_GEN_PROGS_s390x += demand_paging_test
TEST_GEN_PROGS_s390x += dirty_log_test
TEST_GEN_PROGS_s390x += guest_print_test
+69 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Definition for kernel virtual machines on s390x
 *
 * Copyright IBM Corp. 2024
 *
 * Authors:
 *  Christoph Schlameuss <schlameuss@linux.ibm.com>
 */

#ifndef SELFTEST_KVM_DEBUG_PRINT_H
#define SELFTEST_KVM_DEBUG_PRINT_H

#include "asm/ptrace.h"
#include "kvm_util.h"
#include "sie.h"

static inline void print_hex_bytes(const char *name, u64 addr, size_t len)
{
	u64 pos;

	pr_debug("%s (%p)\n", name, (void *)addr);
	pr_debug("            0/0x00---------|");
	if (len > 8)
		pr_debug(" 8/0x08---------|");
	if (len > 16)
		pr_debug(" 16/0x10--------|");
	if (len > 24)
		pr_debug(" 24/0x18--------|");
	for (pos = 0; pos < len; pos += 8) {
		if ((pos % 32) == 0)
			pr_debug("\n %3lu 0x%.3lx ", pos, pos);
		pr_debug(" %16lx", *((u64 *)(addr + pos)));
	}
	pr_debug("\n");
}

static inline void print_hex(const char *name, u64 addr)
{
	print_hex_bytes(name, addr, 512);
}

static inline void print_psw(struct kvm_run *run, struct kvm_s390_sie_block *sie_block)
{
	pr_debug("flags:0x%x psw:0x%.16llx:0x%.16llx exit:%u %s\n",
		 run->flags,
		 run->psw_mask, run->psw_addr,
		 run->exit_reason, exit_reason_str(run->exit_reason));
	pr_debug("sie_block psw:0x%.16llx:0x%.16llx\n",
		 sie_block->psw_mask, sie_block->psw_addr);
}

static inline void print_run(struct kvm_run *run, struct kvm_s390_sie_block *sie_block)
{
	print_hex_bytes("run", (u64)run, 0x150);
	print_hex("sie_block", (u64)sie_block);
	print_psw(run, sie_block);
}

static inline void print_regs(struct kvm_run *run)
{
	struct kvm_sync_regs *sync_regs = &run->s.regs;

	print_hex_bytes("GPRS", (u64)sync_regs->gprs, 8 * NUM_GPRS);
	print_hex_bytes("ACRS", (u64)sync_regs->acrs, 4 * NUM_ACRS);
	print_hex_bytes("CRS", (u64)sync_regs->crs, 8 * NUM_CRS);
}

#endif /* SELFTEST_KVM_DEBUG_PRINT_H */
Loading