From caf757c609445b01ad845df160369d8ccfd97d5b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 6 Sep 2012 14:42:13 +0200 Subject: s390/sysinfo,stsi: change return code handling Change return code handling of the stsi() function: In case function code 0 was specified the return value is the current configuration level (already shifted). That way all the code that actually copied the stsi_0() function can go away. Otherwise the return value is 0 (success) or negative to indicate an error (currently only -EOPNOTSUPP). Also stsi() is no longer an inline function. The function is not performance critical, but every caller would generate an exception table entry for this function. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/early.c | 6 +++--- arch/s390/kernel/lgr.c | 29 ++++++++++------------------- arch/s390/kernel/sysinfo.c | 43 ++++++++++++++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 33 deletions(-) (limited to 'arch/s390/kernel') diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index e8000d5ff533..7f4717675c19 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -222,12 +222,12 @@ static noinline __init void detect_machine_type(void) struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page; /* Check current-configuration-level */ - if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) { + if (stsi(NULL, 0, 0, 0) <= 2) { S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR; return; } /* Get virtual-machine cpu information. */ - if (stsi(vmms, 3, 2, 2) == -ENOSYS || !vmms->count) + if (stsi(vmms, 3, 2, 2) || !vmms->count) return; /* Running under KVM? If not we assume z/VM */ @@ -246,7 +246,7 @@ static __init void setup_topology(void) return; S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY; for (max_mnest = 6; max_mnest > 1; max_mnest--) { - if (stsi(&sysinfo_page, 15, 1, max_mnest) != -ENOSYS) + if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0) break; } topology_max_mnest = max_mnest; diff --git a/arch/s390/kernel/lgr.c b/arch/s390/kernel/lgr.c index eca94e74d19a..6ea6d69339b5 100644 --- a/arch/s390/kernel/lgr.c +++ b/arch/s390/kernel/lgr.c @@ -50,16 +50,6 @@ static struct lgr_info lgr_info_last; static struct lgr_info lgr_info_cur; static struct debug_info *lgr_dbf; -/* - * Return number of valid stsi levels - */ -static inline int stsi_0(void) -{ - int rc = stsi(NULL, 0, 0, 0); - - return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28); -} - /* * Copy buffer and then convert it to ASCII */ @@ -76,7 +66,7 @@ static void lgr_stsi_1_1_1(struct lgr_info *lgr_info) { struct sysinfo_1_1_1 *si = (void *) lgr_page; - if (stsi(si, 1, 1, 1) == -ENOSYS) + if (stsi(si, 1, 1, 1)) return; cpascii(lgr_info->manufacturer, si->manufacturer, sizeof(si->manufacturer)); @@ -93,7 +83,7 @@ static void lgr_stsi_2_2_2(struct lgr_info *lgr_info) { struct sysinfo_2_2_2 *si = (void *) lgr_page; - if (stsi(si, 2, 2, 2) == -ENOSYS) + if (stsi(si, 2, 2, 2)) return; cpascii(lgr_info->name, si->name, sizeof(si->name)); memcpy(&lgr_info->lpar_number, &si->lpar_number, @@ -108,7 +98,7 @@ static void lgr_stsi_3_2_2(struct lgr_info *lgr_info) struct sysinfo_3_2_2 *si = (void *) lgr_page; int i; - if (stsi(si, 3, 2, 2) == -ENOSYS) + if (stsi(si, 3, 2, 2)) return; for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) { cpascii(lgr_info->vm[i].name, si->vm[i].name, @@ -124,16 +114,17 @@ static void lgr_stsi_3_2_2(struct lgr_info *lgr_info) */ static void lgr_info_get(struct lgr_info *lgr_info) { + int level; + memset(lgr_info, 0, sizeof(*lgr_info)); stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list)); - lgr_info->level = stsi_0(); - if (lgr_info->level == -ENOSYS) - return; - if (lgr_info->level >= 1) + level = stsi(NULL, 0, 0, 0); + lgr_info->level = level; + if (level >= 1) lgr_stsi_1_1_1(lgr_info); - if (lgr_info->level >= 2) + if (level >= 2) lgr_stsi_2_2_2(lgr_info); - if (lgr_info->level >= 3) + if (level >= 3) lgr_stsi_3_2_2(lgr_info); } diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 2af4ee67fe52..62f89d98e880 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -24,18 +24,38 @@ int topology_max_mnest; -static inline int stsi_0(void) +/* + * stsi - store system information + * + * Returns the current configuration level if function code 0 was specified. + * Otherwise returns 0 on success or a negative value on error. + */ +int stsi(void *sysinfo, int fc, int sel1, int sel2) { - int rc = stsi(NULL, 0, 0, 0); - - return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28); + register int r0 asm("0") = (fc << 28) | sel1; + register int r1 asm("1") = sel2; + int rc = 0; + + asm volatile( + " stsi 0(%3)\n" + "0: jz 2f\n" + "1: lhi %1,%4\n" + "2:\n" + EX_TABLE(0b, 1b) + : "+d" (r0), "+d" (rc) + : "d" (r1), "a" (sysinfo), "K" (-EOPNOTSUPP) + : "cc", "memory"); + if (rc) + return rc; + return fc ? 0 : ((unsigned int) r0) >> 28; } +EXPORT_SYMBOL(stsi); static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) { int i; - if (stsi(info, 1, 1, 1) == -ENOSYS) + if (stsi(info, 1, 1, 1)) return; EBCASC(info->manufacturer, sizeof(info->manufacturer)); EBCASC(info->type, sizeof(info->type)); @@ -97,7 +117,8 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) seq_putc(m, '\n'); if (!MACHINE_HAS_TOPOLOGY) return; - stsi(info, 15, 1, topology_max_mnest); + if (stsi(info, 15, 1, topology_max_mnest)) + return; seq_printf(m, "CPU Topology HW: "); for (i = 0; i < TOPOLOGY_NR_MAG; i++) seq_printf(m, " %d", info->mag[i]); @@ -116,7 +137,7 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info) struct sysinfo_1_2_2_extension *ext; int i; - if (stsi(info, 1, 2, 2) == -ENOSYS) + if (stsi(info, 1, 2, 2)) return; ext = (struct sysinfo_1_2_2_extension *) ((unsigned long) info + info->acc_offset); @@ -152,7 +173,7 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info) static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info) { - if (stsi(info, 2, 2, 2) == -ENOSYS) + if (stsi(info, 2, 2, 2)) return; EBCASC(info->name, sizeof(info->name)); seq_putc(m, '\n'); @@ -179,7 +200,7 @@ static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) { int i; - if (stsi(info, 3, 2, 2) == -ENOSYS) + if (stsi(info, 3, 2, 2)) return; for (i = 0; i < info->count; i++) { EBCASC(info->vm[i].name, sizeof(info->vm[i].name)); @@ -202,7 +223,7 @@ static int sysinfo_show(struct seq_file *m, void *v) if (!info) return 0; - level = stsi_0(); + level = stsi(NULL, 0, 0, 0); if (level >= 1) stsi_1_1_1(m, info); if (level >= 1) @@ -365,7 +386,7 @@ void s390_adjust_jiffies(void) if (!info) return; - if (stsi(info, 1, 2, 2) != -ENOSYS) { + if (stsi(info, 1, 2, 2) == 0) { /* * Major sigh. The cpu capability encoding is "special". * If the first 9 bits of info->capability are 0 then it -- cgit v1.2.3-59-g8ed1b