Hi Srinivasan, I love your patch! Yet something to improve: [auto build test ERROR on v4.17-rc5] [also build test ERROR on next-20180517] [cannot apply to tip/x86/core] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/kys-linuxonhyperv-com/X86-Hyper-V-APIC-enlightenments/20180520-040432 config: x86_64-randconfig-s5-05201710 (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): arch/x86/hyperv/hv_apic.c: In function 'hv_apic_read': arch/x86/hyperv/hv_apic.c:70:10: error: implicit declaration of function 'native_apic_mem_read'; did you mean 'hv_apic_icr_read'? [-Werror=implicit-function-declaration] return native_apic_mem_read(reg); ^~~~~~~~~~~~~~~~~~~~ hv_apic_icr_read arch/x86/hyperv/hv_apic.c: In function 'hv_apic_write': arch/x86/hyperv/hv_apic.c:84:3: error: implicit declaration of function 'native_apic_mem_write'; did you mean 'hv_apic_icr_write'? [-Werror=implicit-function-declaration] native_apic_mem_write(reg, val); ^~~~~~~~~~~~~~~~~~~~~ hv_apic_icr_write arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi': >> arch/x86/hyperv/hv_apic.c:154:12: error: invalid use of undefined type 'struct apic' orig_apic.send_IPI(cpu, vector); ^ arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_mask': arch/x86/hyperv/hv_apic.c:160:12: error: invalid use of undefined type 'struct apic' orig_apic.send_IPI_mask(mask, vector); ^ arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_mask_allbutself': arch/x86/hyperv/hv_apic.c:173:12: error: invalid use of undefined type 'struct apic' orig_apic.send_IPI_mask_allbutself(mask, vector); ^ arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_all': arch/x86/hyperv/hv_apic.c:184:12: error: invalid use of undefined type 'struct apic' orig_apic.send_IPI_all(vector); ^ arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_self': arch/x86/hyperv/hv_apic.c:190:12: error: invalid use of undefined type 'struct apic' orig_apic.send_IPI_self(vector); ^ arch/x86/hyperv/hv_apic.c: In function 'hv_apic_init': >> arch/x86/hyperv/hv_apic.c:200:16: error: 'apic' undeclared (first use in this function) orig_apic = *apic; ^~~~ arch/x86/hyperv/hv_apic.c:200:16: note: each undeclared identifier is reported only once for each function it appears in >> arch/x86/hyperv/hv_apic.c:200:13: error: 'orig_apic' has an incomplete type 'struct apic' orig_apic = *apic; ^ arch/x86/hyperv/hv_apic.c:212:3: error: implicit declaration of function 'apic_set_eoi_write'; did you mean 'hv_apic_eoi_write'? [-Werror=implicit-function-declaration] apic_set_eoi_write(hv_apic_eoi_write); ^~~~~~~~~~~~~~~~~~ hv_apic_eoi_write arch/x86/hyperv/hv_apic.c: At top level: >> arch/x86/hyperv/hv_apic.c:36:20: error: storage size of 'orig_apic' isn't known static struct apic orig_apic; ^~~~~~~~~ cc1: some warnings being treated as errors vim +154 arch/x86/hyperv/hv_apic.c 35 > 36 static struct apic orig_apic; 37 38 static u64 hv_apic_icr_read(void) 39 { 40 u64 reg_val; 41 42 rdmsrl(HV_X64_MSR_ICR, reg_val); 43 return reg_val; 44 } 45 46 static void hv_apic_icr_write(u32 low, u32 id) 47 { 48 u64 reg_val; 49 50 reg_val = SET_APIC_DEST_FIELD(id); 51 reg_val = reg_val << 32; 52 reg_val |= low; 53 54 wrmsrl(HV_X64_MSR_ICR, reg_val); 55 } 56 57 static u32 hv_apic_read(u32 reg) 58 { 59 u32 reg_val, hi; 60 61 switch (reg) { 62 case APIC_EOI: 63 rdmsr(HV_X64_MSR_EOI, reg_val, hi); 64 return reg_val; 65 case APIC_TASKPRI: 66 rdmsr(HV_X64_MSR_TPR, reg_val, hi); 67 return reg_val; 68 69 default: 70 return native_apic_mem_read(reg); 71 } 72 } 73 74 static void hv_apic_write(u32 reg, u32 val) 75 { 76 switch (reg) { 77 case APIC_EOI: 78 wrmsr(HV_X64_MSR_EOI, val, 0); 79 break; 80 case APIC_TASKPRI: 81 wrmsr(HV_X64_MSR_TPR, val, 0); 82 break; 83 default: > 84 native_apic_mem_write(reg, val); 85 } 86 } 87 88 static void hv_apic_eoi_write(u32 reg, u32 val) 89 { 90 wrmsr(HV_X64_MSR_EOI, val, 0); 91 } 92 93 /* 94 * IPI implementation on Hyper-V. 95 */ 96 static bool __send_ipi_mask(const struct cpumask *mask, int vector) 97 { 98 int cur_cpu, vcpu; 99 struct ipi_arg_non_ex **arg; 100 struct ipi_arg_non_ex *ipi_arg; 101 int ret = 1; 102 unsigned long flags; 103 104 if (cpumask_empty(mask)) 105 return true; 106 107 if (!hv_hypercall_pg) 108 return false; 109 110 if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR)) 111 return false; 112 113 local_irq_save(flags); 114 arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg); 115 116 ipi_arg = *arg; 117 if (unlikely(!ipi_arg)) 118 goto ipi_mask_done; 119 120 ipi_arg->vector = vector; 121 ipi_arg->reserved = 0; 122 ipi_arg->cpu_mask = 0; 123 124 for_each_cpu(cur_cpu, mask) { 125 vcpu = hv_cpu_number_to_vp_number(cur_cpu); 126 /* 127 * This particular version of the IPI hypercall can 128 * only target upto 64 CPUs. 129 */ 130 if (vcpu >= 64) 131 goto ipi_mask_done; 132 133 __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask); 134 } 135 136 ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL); 137 138 ipi_mask_done: 139 local_irq_restore(flags); 140 return ((ret == 0) ? true : false); 141 } 142 143 static bool __send_ipi_one(int cpu, int vector) 144 { 145 struct cpumask mask = CPU_MASK_NONE; 146 147 cpumask_set_cpu(cpu, &mask); 148 return __send_ipi_mask(&mask, vector); 149 } 150 151 static void hv_send_ipi(int cpu, int vector) 152 { 153 if (!__send_ipi_one(cpu, vector)) > 154 orig_apic.send_IPI(cpu, vector); 155 } 156 157 static void hv_send_ipi_mask(const struct cpumask *mask, int vector) 158 { 159 if (!__send_ipi_mask(mask, vector)) 160 orig_apic.send_IPI_mask(mask, vector); 161 } 162 163 static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector) 164 { 165 unsigned int this_cpu = smp_processor_id(); 166 struct cpumask new_mask; 167 const struct cpumask *local_mask; 168 169 cpumask_copy(&new_mask, mask); 170 cpumask_clear_cpu(this_cpu, &new_mask); 171 local_mask = &new_mask; 172 if (!__send_ipi_mask(local_mask, vector)) 173 orig_apic.send_IPI_mask_allbutself(mask, vector); 174 } 175 176 static void hv_send_ipi_allbutself(int vector) 177 { 178 hv_send_ipi_mask_allbutself(cpu_online_mask, vector); 179 } 180 181 static void hv_send_ipi_all(int vector) 182 { 183 if (!__send_ipi_mask(cpu_online_mask, vector)) > 184 orig_apic.send_IPI_all(vector); 185 } 186 187 static void hv_send_ipi_self(int vector) 188 { 189 if (!__send_ipi_one(smp_processor_id(), vector)) > 190 orig_apic.send_IPI_self(vector); 191 } 192 193 void __init hv_apic_init(void) 194 { 195 if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) { 196 pr_info("Hyper-V: Using IPI hypercalls\n"); 197 /* 198 * Set the IPI entry points. 199 */ > 200 orig_apic = *apic; 201 202 apic->send_IPI = hv_send_ipi; 203 apic->send_IPI_mask = hv_send_ipi_mask; 204 apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself; 205 apic->send_IPI_allbutself = hv_send_ipi_allbutself; 206 apic->send_IPI_all = hv_send_ipi_all; 207 apic->send_IPI_self = hv_send_ipi_self; 208 } 209 210 if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) { 211 pr_info("Hyper-V: Using MSR based APIC access\n"); 212 apic_set_eoi_write(hv_apic_eoi_write); 213 apic->read = hv_apic_read; 214 apic->write = hv_apic_write; 215 apic->icr_write = hv_apic_icr_write; 216 apic->icr_read = hv_apic_icr_read; 217 } 218 } 219 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation