Skip to content

Commit

Permalink
KVM: s390: Perform early event mask processing during boot
Browse files Browse the repository at this point in the history
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: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Acked-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
  • Loading branch information
Heinz Graalfs authored and Marcelo Tosatti committed Jun 13, 2012
1 parent 61bde82 commit cd18345
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 14 deletions.
2 changes: 2 additions & 0 deletions arch/s390/include/asm/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
12 changes: 9 additions & 3 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -138,9 +139,14 @@ __setup("condev=", condev_setup);

static void __init set_preferred_console(void)
{
if (MACHINE_IS_KVM)
add_preferred_console("hvc", 0, NULL);
else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
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)
add_preferred_console("ttyS", 0, NULL);
else if (CONSOLE_IS_3270)
add_preferred_console("tty3270", 0, NULL);
Expand Down
10 changes: 0 additions & 10 deletions drivers/s390/char/sclp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions drivers/s390/char/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
38 changes: 38 additions & 0 deletions drivers/s390/char/sclp_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion drivers/s390/kvm/kvm_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <asm/io.h>
#include <asm/kvm_para.h>
#include <asm/kvm_virtio.h>
#include <asm/sclp.h>
#include <asm/setup.h>
#include <asm/irq.h>

Expand Down Expand Up @@ -468,7 +469,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)

static int __init s390_virtio_console_init(void)
{
if (!MACHINE_IS_KVM)
if (sclp_has_vt220() || sclp_has_linemode())
return -ENODEV;
return virtio_cons_early_init(early_put_chars);
}
Expand Down

0 comments on commit cd18345

Please sign in to comment.