mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
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: 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>
This commit is contained in:
parent
61bde82cae
commit
cd1834591f
6 changed files with 61 additions and 14 deletions
|
@ -55,5 +55,7 @@ int sclp_chp_configure(struct chp_id chpid);
|
||||||
int sclp_chp_deconfigure(struct chp_id chpid);
|
int sclp_chp_deconfigure(struct chp_id chpid);
|
||||||
int sclp_chp_read_info(struct sclp_chp_info *info);
|
int sclp_chp_read_info(struct sclp_chp_info *info);
|
||||||
void sclp_get_ipl_info(struct sclp_ipl_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 */
|
#endif /* _ASM_S390_SCLP_H */
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include <asm/kvm_virtio.h>
|
#include <asm/kvm_virtio.h>
|
||||||
#include <asm/diag.h>
|
#include <asm/diag.h>
|
||||||
#include <asm/os_info.h>
|
#include <asm/os_info.h>
|
||||||
|
#include <asm/sclp.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
long psw_kernel_bits = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
|
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)
|
static void __init set_preferred_console(void)
|
||||||
{
|
{
|
||||||
if (MACHINE_IS_KVM)
|
if (MACHINE_IS_KVM) {
|
||||||
add_preferred_console("hvc", 0, NULL);
|
if (sclp_has_vt220())
|
||||||
else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
|
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);
|
add_preferred_console("ttyS", 0, NULL);
|
||||||
else if (CONSOLE_IS_3270)
|
else if (CONSOLE_IS_3270)
|
||||||
add_preferred_console("tty3270", 0, NULL);
|
add_preferred_console("tty3270", 0, NULL);
|
||||||
|
|
|
@ -654,16 +654,6 @@ sclp_remove_processed(struct sccb_header *sccb)
|
||||||
|
|
||||||
EXPORT_SYMBOL(sclp_remove_processed);
|
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. */
|
/* Prepare init mask request. Called while sclp_lock is locked. */
|
||||||
static inline void
|
static inline void
|
||||||
__sclp_make_init_req(u32 receive_mask, u32 send_mask)
|
__sclp_make_init_req(u32 receive_mask, u32 send_mask)
|
||||||
|
|
|
@ -88,6 +88,16 @@ struct sccb_header {
|
||||||
u16 response_code;
|
u16 response_code;
|
||||||
} __attribute__((packed));
|
} __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;
|
extern u64 sclp_facilities;
|
||||||
#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
|
#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
|
||||||
#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
|
#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct read_info_sccb {
|
||||||
u8 _reserved5[4096 - 112]; /* 112-4095 */
|
u8 _reserved5[4096 - 112]; /* 112-4095 */
|
||||||
} __attribute__((packed, aligned(PAGE_SIZE)));
|
} __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 struct read_info_sccb __initdata early_read_info_sccb;
|
||||||
static int __initdata early_read_info_sccb_valid;
|
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)
|
void __init sclp_facilities_detect(void)
|
||||||
{
|
{
|
||||||
struct read_info_sccb *sccb;
|
struct read_info_sccb *sccb;
|
||||||
|
@ -119,6 +133,30 @@ void __init sclp_facilities_detect(void)
|
||||||
rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
|
rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
|
||||||
rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
|
rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
|
||||||
rzm <<= 20;
|
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)
|
unsigned long long sclp_get_rnmax(void)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/kvm_para.h>
|
#include <asm/kvm_para.h>
|
||||||
#include <asm/kvm_virtio.h>
|
#include <asm/kvm_virtio.h>
|
||||||
|
#include <asm/sclp.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
@ -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)
|
static int __init s390_virtio_console_init(void)
|
||||||
{
|
{
|
||||||
if (!MACHINE_IS_KVM)
|
if (sclp_has_vt220() || sclp_has_linemode())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
return virtio_cons_early_init(early_put_chars);
|
return virtio_cons_early_init(early_put_chars);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue