mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
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 <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
94f2b9e25d
commit
caf757c609
6 changed files with 51 additions and 60 deletions
|
@ -153,21 +153,7 @@ struct sysinfo_15_1_x {
|
||||||
union topology_entry tle[0];
|
union topology_entry tle[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
|
int stsi(void *sysinfo, int fc, int sel1, int sel2);
|
||||||
{
|
|
||||||
register int r0 asm("0") = (fc << 28) | sel1;
|
|
||||||
register int r1 asm("1") = sel2;
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
" stsi 0(%2)\n"
|
|
||||||
"0: jz 2f\n"
|
|
||||||
"1: lhi %0,%3\n"
|
|
||||||
"2:\n"
|
|
||||||
EX_TABLE(0b, 1b)
|
|
||||||
: "+d" (r0) : "d" (r1), "a" (sysinfo), "K" (-ENOSYS)
|
|
||||||
: "cc", "memory");
|
|
||||||
return r0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Service level reporting interface.
|
* Service level reporting interface.
|
||||||
|
|
|
@ -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;
|
struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page;
|
||||||
|
|
||||||
/* Check current-configuration-level */
|
/* 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;
|
S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Get virtual-machine cpu information. */
|
/* Get virtual-machine cpu information. */
|
||||||
if (stsi(vmms, 3, 2, 2) == -ENOSYS || !vmms->count)
|
if (stsi(vmms, 3, 2, 2) || !vmms->count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Running under KVM? If not we assume z/VM */
|
/* Running under KVM? If not we assume z/VM */
|
||||||
|
@ -246,7 +246,7 @@ static __init void setup_topology(void)
|
||||||
return;
|
return;
|
||||||
S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
|
S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY;
|
||||||
for (max_mnest = 6; max_mnest > 1; max_mnest--) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
topology_max_mnest = max_mnest;
|
topology_max_mnest = max_mnest;
|
||||||
|
|
|
@ -50,16 +50,6 @@ static struct lgr_info lgr_info_last;
|
||||||
static struct lgr_info lgr_info_cur;
|
static struct lgr_info lgr_info_cur;
|
||||||
static struct debug_info *lgr_dbf;
|
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
|
* 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;
|
struct sysinfo_1_1_1 *si = (void *) lgr_page;
|
||||||
|
|
||||||
if (stsi(si, 1, 1, 1) == -ENOSYS)
|
if (stsi(si, 1, 1, 1))
|
||||||
return;
|
return;
|
||||||
cpascii(lgr_info->manufacturer, si->manufacturer,
|
cpascii(lgr_info->manufacturer, si->manufacturer,
|
||||||
sizeof(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;
|
struct sysinfo_2_2_2 *si = (void *) lgr_page;
|
||||||
|
|
||||||
if (stsi(si, 2, 2, 2) == -ENOSYS)
|
if (stsi(si, 2, 2, 2))
|
||||||
return;
|
return;
|
||||||
cpascii(lgr_info->name, si->name, sizeof(si->name));
|
cpascii(lgr_info->name, si->name, sizeof(si->name));
|
||||||
memcpy(&lgr_info->lpar_number, &si->lpar_number,
|
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;
|
struct sysinfo_3_2_2 *si = (void *) lgr_page;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (stsi(si, 3, 2, 2) == -ENOSYS)
|
if (stsi(si, 3, 2, 2))
|
||||||
return;
|
return;
|
||||||
for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) {
|
for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) {
|
||||||
cpascii(lgr_info->vm[i].name, si->vm[i].name,
|
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)
|
static void lgr_info_get(struct lgr_info *lgr_info)
|
||||||
{
|
{
|
||||||
|
int level;
|
||||||
|
|
||||||
memset(lgr_info, 0, sizeof(*lgr_info));
|
memset(lgr_info, 0, sizeof(*lgr_info));
|
||||||
stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list));
|
stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list));
|
||||||
lgr_info->level = stsi_0();
|
level = stsi(NULL, 0, 0, 0);
|
||||||
if (lgr_info->level == -ENOSYS)
|
lgr_info->level = level;
|
||||||
return;
|
if (level >= 1)
|
||||||
if (lgr_info->level >= 1)
|
|
||||||
lgr_stsi_1_1_1(lgr_info);
|
lgr_stsi_1_1_1(lgr_info);
|
||||||
if (lgr_info->level >= 2)
|
if (level >= 2)
|
||||||
lgr_stsi_2_2_2(lgr_info);
|
lgr_stsi_2_2_2(lgr_info);
|
||||||
if (lgr_info->level >= 3)
|
if (level >= 3)
|
||||||
lgr_stsi_3_2_2(lgr_info);
|
lgr_stsi_3_2_2(lgr_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,18 +24,38 @@
|
||||||
|
|
||||||
int topology_max_mnest;
|
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);
|
register int r0 asm("0") = (fc << 28) | sel1;
|
||||||
|
register int r1 asm("1") = sel2;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
|
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)
|
static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (stsi(info, 1, 1, 1) == -ENOSYS)
|
if (stsi(info, 1, 1, 1))
|
||||||
return;
|
return;
|
||||||
EBCASC(info->manufacturer, sizeof(info->manufacturer));
|
EBCASC(info->manufacturer, sizeof(info->manufacturer));
|
||||||
EBCASC(info->type, sizeof(info->type));
|
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');
|
seq_putc(m, '\n');
|
||||||
if (!MACHINE_HAS_TOPOLOGY)
|
if (!MACHINE_HAS_TOPOLOGY)
|
||||||
return;
|
return;
|
||||||
stsi(info, 15, 1, topology_max_mnest);
|
if (stsi(info, 15, 1, topology_max_mnest))
|
||||||
|
return;
|
||||||
seq_printf(m, "CPU Topology HW: ");
|
seq_printf(m, "CPU Topology HW: ");
|
||||||
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
|
for (i = 0; i < TOPOLOGY_NR_MAG; i++)
|
||||||
seq_printf(m, " %d", info->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;
|
struct sysinfo_1_2_2_extension *ext;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (stsi(info, 1, 2, 2) == -ENOSYS)
|
if (stsi(info, 1, 2, 2))
|
||||||
return;
|
return;
|
||||||
ext = (struct sysinfo_1_2_2_extension *)
|
ext = (struct sysinfo_1_2_2_extension *)
|
||||||
((unsigned long) info + info->acc_offset);
|
((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)
|
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;
|
return;
|
||||||
EBCASC(info->name, sizeof(info->name));
|
EBCASC(info->name, sizeof(info->name));
|
||||||
seq_putc(m, '\n');
|
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;
|
int i;
|
||||||
|
|
||||||
if (stsi(info, 3, 2, 2) == -ENOSYS)
|
if (stsi(info, 3, 2, 2))
|
||||||
return;
|
return;
|
||||||
for (i = 0; i < info->count; i++) {
|
for (i = 0; i < info->count; i++) {
|
||||||
EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
|
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)
|
if (!info)
|
||||||
return 0;
|
return 0;
|
||||||
level = stsi_0();
|
level = stsi(NULL, 0, 0, 0);
|
||||||
if (level >= 1)
|
if (level >= 1)
|
||||||
stsi_1_1_1(m, info);
|
stsi_1_1_1(m, info);
|
||||||
if (level >= 1)
|
if (level >= 1)
|
||||||
|
@ -365,7 +386,7 @@ void s390_adjust_jiffies(void)
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (stsi(info, 1, 2, 2) != -ENOSYS) {
|
if (stsi(info, 1, 2, 2) == 0) {
|
||||||
/*
|
/*
|
||||||
* Major sigh. The cpu capability encoding is "special".
|
* Major sigh. The cpu capability encoding is "special".
|
||||||
* If the first 9 bits of info->capability are 0 then it
|
* If the first 9 bits of info->capability are 0 then it
|
||||||
|
|
|
@ -211,7 +211,7 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
|
||||||
spin_unlock(&fi->lock);
|
spin_unlock(&fi->lock);
|
||||||
|
|
||||||
/* deal with other level 3 hypervisors */
|
/* deal with other level 3 hypervisors */
|
||||||
if (stsi(mem, 3, 2, 2) == -ENOSYS)
|
if (stsi(mem, 3, 2, 2))
|
||||||
mem->count = 0;
|
mem->count = 0;
|
||||||
if (mem->count < 8)
|
if (mem->count < 8)
|
||||||
mem->count++;
|
mem->count++;
|
||||||
|
@ -259,7 +259,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
|
||||||
mem = get_zeroed_page(GFP_KERNEL);
|
mem = get_zeroed_page(GFP_KERNEL);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
if (stsi((void *) mem, fc, sel1, sel2) == -ENOSYS)
|
if (stsi((void *) mem, fc, sel1, sel2))
|
||||||
goto out_mem;
|
goto out_mem;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
|
|
@ -2993,7 +2993,7 @@ static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
|
||||||
struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
|
struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
|
||||||
struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
|
struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
|
||||||
struct ccw_dev_id ccwid;
|
struct ccw_dev_id ccwid;
|
||||||
int level, rc;
|
int level;
|
||||||
|
|
||||||
tid->chpid = card->info.chpid;
|
tid->chpid = card->info.chpid;
|
||||||
ccw_device_get_id(CARD_RDEV(card), &ccwid);
|
ccw_device_get_id(CARD_RDEV(card), &ccwid);
|
||||||
|
@ -3001,17 +3001,10 @@ static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
|
||||||
tid->devno = ccwid.devno;
|
tid->devno = ccwid.devno;
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return;
|
||||||
|
level = stsi(NULL, 0, 0, 0);
|
||||||
rc = stsi(NULL, 0, 0, 0);
|
if ((level >= 2) && (stsi(info222, 2, 2, 2) == 0))
|
||||||
if (rc == -ENOSYS)
|
|
||||||
level = rc;
|
|
||||||
else
|
|
||||||
level = (((unsigned int) rc) >> 28);
|
|
||||||
|
|
||||||
if ((level >= 2) && (stsi(info222, 2, 2, 2) != -ENOSYS))
|
|
||||||
tid->lparnr = info222->lpar_number;
|
tid->lparnr = info222->lpar_number;
|
||||||
|
if ((level >= 3) && (stsi(info322, 3, 2, 2) == 0)) {
|
||||||
if ((level >= 3) && (stsi(info322, 3, 2, 2) != -ENOSYS)) {
|
|
||||||
EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
|
EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
|
||||||
memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
|
memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue