1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Store System Information tests 4 * 5 * Copyright (c) 2019 IBM Corp 6 * 7 * Authors: 8 * Janosch Frank <frankja@linux.ibm.com> 9 */ 10 11 #include <libcflat.h> 12 #include <asm/page.h> 13 #include <asm/asm-offsets.h> 14 #include <asm/interrupt.h> 15 #include <smp.h> 16 #include <stsi.h> 17 18 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); 19 20 static void test_specs(void) 21 { 22 report_prefix_push("specification"); 23 24 report_prefix_push("inv r0"); 25 expect_pgm_int(); 26 stsi(pagebuf, 0, 1 << 8, 0); 27 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 28 report_prefix_pop(); 29 30 report_prefix_push("inv r1"); 31 expect_pgm_int(); 32 stsi(pagebuf, 1, 0, 1 << 16); 33 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 34 report_prefix_pop(); 35 36 report_prefix_push("unaligned"); 37 expect_pgm_int(); 38 stsi(pagebuf + 42, 1, 1, 1); 39 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 40 report_prefix_pop(); 41 42 report_prefix_pop(); 43 } 44 45 static void test_priv(void) 46 { 47 report_prefix_push("privileged"); 48 expect_pgm_int(); 49 enter_pstate(); 50 stsi(pagebuf, 0, 0, 0); 51 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 52 report_prefix_pop(); 53 } 54 55 static void test_fc(void) 56 { 57 report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc"); 58 report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1"); 59 report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2"); 60 report(stsi_get_fc() >= 2, "query fc >= 2"); 61 } 62 63 static void test_3_2_2(void) 64 { 65 int rc; 66 /* EBCDIC for "kvm-unit" */ 67 const uint8_t vm_name[] = { 0x92, 0xa5, 0x94, 0x60, 0xa4, 0x95, 0x89, 68 0xa3 }; 69 const uint8_t uuid[] = { 0x0f, 0xb8, 0x4a, 0x86, 0x72, 0x7c, 70 0x11, 0xea, 0xbc, 0x55, 0x02, 0x42, 0xac, 0x13, 71 0x00, 0x03 }; 72 /* EBCDIC for "KVM/" */ 73 const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 }; 74 const char vm_name_ext[] = "kvm-unit-test"; 75 struct sysinfo_3_2_2 *data = (void *)pagebuf; 76 77 report_prefix_push("3.2.2"); 78 79 /* Is the function code available at all? */ 80 if (stsi_get_fc() < 3) { 81 report_skip("Running under lpar, no level 3 to test."); 82 goto out; 83 } 84 85 rc = stsi(pagebuf, 3, 2, 2); 86 report(!rc, "call"); 87 88 /* For now we concentrate on KVM/QEMU */ 89 if (memcmp(&data->vm[0].cpi, cpi_kvm, sizeof(cpi_kvm))) { 90 report_skip("Not running under KVM/QEMU."); 91 goto out; 92 } 93 94 report(!memcmp(data->vm[0].uuid, uuid, sizeof(uuid)), "uuid"); 95 report(data->vm[0].conf_cpus == smp_query_num_cpus(), "cpu count configured"); 96 report(data->vm[0].total_cpus == 97 data->vm[0].reserved_cpus + data->vm[0].conf_cpus, 98 "cpu count total == conf + reserved"); 99 report(data->vm[0].standby_cpus == 0, "cpu count standby"); 100 report(!memcmp(data->vm[0].name, vm_name, sizeof(data->vm[0].name)), 101 "VM name == kvm-unit-test"); 102 103 if (data->vm[0].ext_name_encoding != 2) { 104 report_skip("Extended VM names are not UTF-8."); 105 goto out; 106 } 107 report(!memcmp(data->ext_names[0], vm_name_ext, sizeof(vm_name_ext)), 108 "ext VM name == kvm-unit-test"); 109 110 out: 111 report_prefix_pop(); 112 } 113 114 int main(void) 115 { 116 report_prefix_push("stsi"); 117 test_priv(); 118 test_specs(); 119 test_fc(); 120 test_3_2_2(); 121 return report_summary(); 122 } 123