Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd183459 authored by Heinz Graalfs's avatar Heinz Graalfs Committed by Marcelo Tosatti
Browse files

KVM: s390: Perform early event mask processing during boot



For processing under KVM it is required to detect
the actual SCLP console type in order to set it as
preferred console.

Signed-off-by: default avatarHeinz Graalfs <graalfs@linux.vnet.ibm.com>
Acked-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Acked-by: default avatarPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 61bde82c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -55,5 +55,7 @@ int sclp_chp_configure(struct chp_id chpid);
int sclp_chp_deconfigure(struct chp_id chpid);
int sclp_chp_read_info(struct sclp_chp_info *info);
void sclp_get_ipl_info(struct sclp_ipl_info *info);
bool sclp_has_linemode(void);
bool sclp_has_vt220(void);

#endif /* _ASM_S390_SCLP_H */
+9 −3
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include <asm/kvm_virtio.h>
#include <asm/diag.h>
#include <asm/os_info.h>
#include <asm/sclp.h>
#include "entry.h"

long psw_kernel_bits	= PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
@@ -138,9 +139,14 @@ __setup("condev=", condev_setup);

static void __init set_preferred_console(void)
{
	if (MACHINE_IS_KVM)
	if (MACHINE_IS_KVM) {
		if (sclp_has_vt220())
			add_preferred_console("ttyS", 1, NULL);
		else if (sclp_has_linemode())
			add_preferred_console("ttyS", 0, NULL);
		else
			add_preferred_console("hvc", 0, NULL);
	else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
	} else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
		add_preferred_console("ttyS", 0, NULL);
	else if (CONSOLE_IS_3270)
		add_preferred_console("tty3270", 0, NULL);
+0 −10
Original line number Diff line number Diff line
@@ -654,16 +654,6 @@ sclp_remove_processed(struct sccb_header *sccb)

EXPORT_SYMBOL(sclp_remove_processed);

struct init_sccb {
	struct sccb_header header;
	u16 _reserved;
	u16 mask_length;
	sccb_mask_t receive_mask;
	sccb_mask_t send_mask;
	sccb_mask_t sclp_receive_mask;
	sccb_mask_t sclp_send_mask;
} __attribute__((packed));

/* Prepare init mask request. Called while sclp_lock is locked. */
static inline void
__sclp_make_init_req(u32 receive_mask, u32 send_mask)
+10 −0
Original line number Diff line number Diff line
@@ -88,6 +88,16 @@ struct sccb_header {
	u16	response_code;
} __attribute__((packed));

struct init_sccb {
	struct sccb_header header;
	u16 _reserved;
	u16 mask_length;
	sccb_mask_t receive_mask;
	sccb_mask_t send_mask;
	sccb_mask_t sclp_receive_mask;
	sccb_mask_t sclp_send_mask;
} __attribute__((packed));

extern u64 sclp_facilities;
#define SCLP_HAS_CHP_INFO	(sclp_facilities & 0x8000000000000000ULL)
#define SCLP_HAS_CHP_RECONFIG	(sclp_facilities & 0x2000000000000000ULL)
+38 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct read_info_sccb {
	u8	_reserved5[4096 - 112];	/* 112-4095 */
} __attribute__((packed, aligned(PAGE_SIZE)));

static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE);
static struct read_info_sccb __initdata early_read_info_sccb;
static int __initdata early_read_info_sccb_valid;

@@ -104,6 +105,19 @@ static void __init sclp_read_info_early(void)
	}
}

static void __init sclp_event_mask_early(void)
{
	struct init_sccb *sccb = &early_event_mask_sccb;
	int rc;

	do {
		memset(sccb, 0, sizeof(*sccb));
		sccb->header.length = sizeof(*sccb);
		sccb->mask_length = sizeof(sccb_mask_t);
		rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
	} while (rc == -EBUSY);
}

void __init sclp_facilities_detect(void)
{
	struct read_info_sccb *sccb;
@@ -119,6 +133,30 @@ void __init sclp_facilities_detect(void)
	rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
	rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
	rzm <<= 20;

	sclp_event_mask_early();
}

bool __init sclp_has_linemode(void)
{
	struct init_sccb *sccb = &early_event_mask_sccb;

	if (sccb->header.response_code != 0x20)
		return 0;
	if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))
		return 1;
	return 0;
}

bool __init sclp_has_vt220(void)
{
	struct init_sccb *sccb = &early_event_mask_sccb;

	if (sccb->header.response_code != 0x20)
		return 0;
	if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
		return 1;
	return 0;
}

unsigned long long sclp_get_rnmax(void)
Loading