1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2024 Loongson Technology Corporation Limited 4 */ 5 6 #include <asm/kvm_eiointc.h> 7 #include <asm/kvm_pch_pic.h> 8 #include <asm/kvm_vcpu.h> 9 #include <linux/count_zeros.h> 10 11 /* update the isr according to irq level and route irq to eiointc */ 12 static void pch_pic_update_irq(struct loongarch_pch_pic *s, int irq, int level) 13 { 14 u64 mask = BIT(irq); 15 16 /* 17 * set isr and route irq to eiointc and 18 * the route table is in htmsi_vector[] 19 */ 20 if (level) { 21 if (mask & s->irr & ~s->mask) { 22 s->isr |= mask; 23 irq = s->htmsi_vector[irq]; 24 eiointc_set_irq(s->kvm->arch.eiointc, irq, level); 25 } 26 } else { 27 if (mask & s->isr & ~s->irr) { 28 s->isr &= ~mask; 29 irq = s->htmsi_vector[irq]; 30 eiointc_set_irq(s->kvm->arch.eiointc, irq, level); 31 } 32 } 33 } 34 35 /* update batch irqs, the irq_mask is a bitmap of irqs */ 36 static void pch_pic_update_batch_irqs(struct loongarch_pch_pic *s, u64 irq_mask, int level) 37 { 38 unsigned int irq; 39 DECLARE_BITMAP(irqs, 64) = { BITMAP_FROM_U64(irq_mask) }; 40 41 for_each_set_bit(irq, irqs, 64) 42 pch_pic_update_irq(s, irq, level); 43 } 44 45 /* called when a irq is triggered in pch pic */ 46 void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level) 47 { 48 u64 mask = BIT(irq); 49 50 spin_lock(&s->lock); 51 if (level) 52 s->irr |= mask; /* set irr */ 53 else { 54 /* 55 * In edge triggered mode, 0 does not mean to clear irq 56 * The irr register variable is cleared when cpu writes to the 57 * PCH_PIC_CLEAR_START address area 58 */ 59 if (s->edge & mask) { 60 spin_unlock(&s->lock); 61 return; 62 } 63 s->irr &= ~mask; 64 } 65 pch_pic_update_irq(s, irq, level); 66 spin_unlock(&s->lock); 67 } 68 69 /* msi irq handler */ 70 void pch_msi_set_irq(struct kvm *kvm, int irq, int level) 71 { 72 eiointc_set_irq(kvm->arch.eiointc, irq, level); 73 } 74 75 static int loongarch_pch_pic_read(struct loongarch_pch_pic *s, gpa_t addr, int len, void *val) 76 { 77 int ret = 0, offset; 78 u64 data = 0; 79 void *ptemp; 80 81 offset = addr - s->pch_pic_base; 82 offset -= offset & 7; 83 84 spin_lock(&s->lock); 85 switch (offset) { 86 case PCH_PIC_INT_ID_START ... PCH_PIC_INT_ID_END: 87 data = s->id.data; 88 break; 89 case PCH_PIC_MASK_START ... PCH_PIC_MASK_END: 90 data = s->mask; 91 break; 92 case PCH_PIC_HTMSI_EN_START ... PCH_PIC_HTMSI_EN_END: 93 /* read htmsi enable reg */ 94 data = s->htmsi_en; 95 break; 96 case PCH_PIC_EDGE_START ... PCH_PIC_EDGE_END: 97 /* read edge enable reg */ 98 data = s->edge; 99 break; 100 case PCH_PIC_AUTO_CTRL0_START ... PCH_PIC_AUTO_CTRL0_END: 101 case PCH_PIC_AUTO_CTRL1_START ... PCH_PIC_AUTO_CTRL1_END: 102 /* we only use default mode: fixed interrupt distribution mode */ 103 break; 104 case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END: 105 /* only route to int0: eiointc */ 106 ptemp = s->route_entry + (offset - PCH_PIC_ROUTE_ENTRY_START); 107 data = *(u64 *)ptemp; 108 break; 109 case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END: 110 /* read htmsi vector */ 111 ptemp = s->htmsi_vector + (offset - PCH_PIC_HTMSI_VEC_START); 112 data = *(u64 *)ptemp; 113 break; 114 case PCH_PIC_POLARITY_START ... PCH_PIC_POLARITY_END: 115 data = s->polarity; 116 break; 117 case PCH_PIC_INT_IRR_START: 118 data = s->irr; 119 break; 120 case PCH_PIC_INT_ISR_START: 121 data = s->isr; 122 break; 123 default: 124 ret = -EINVAL; 125 } 126 spin_unlock(&s->lock); 127 128 if (ret == 0) { 129 offset = (addr - s->pch_pic_base) & 7; 130 data = data >> (offset * 8); 131 memcpy(val, &data, len); 132 } 133 134 return ret; 135 } 136 137 static int kvm_pch_pic_read(struct kvm_vcpu *vcpu, 138 struct kvm_io_device *dev, 139 gpa_t addr, int len, void *val) 140 { 141 int ret; 142 struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic; 143 144 if (!s) { 145 kvm_err("%s: pch pic irqchip not valid!\n", __func__); 146 return -EINVAL; 147 } 148 149 if (addr & (len - 1)) { 150 kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); 151 return -EINVAL; 152 } 153 154 /* statistics of pch pic reading */ 155 vcpu->stat.pch_pic_read_exits++; 156 ret = loongarch_pch_pic_read(s, addr, len, val); 157 158 return ret; 159 } 160 161 static int loongarch_pch_pic_write(struct loongarch_pch_pic *s, gpa_t addr, 162 int len, const void *val) 163 { 164 int ret = 0, offset; 165 u64 old, data, mask; 166 void *ptemp; 167 168 switch (len) { 169 case 1: 170 data = *(u8 *)val; 171 mask = 0xFF; 172 break; 173 case 2: 174 data = *(u16 *)val; 175 mask = USHRT_MAX; 176 break; 177 case 4: 178 data = *(u32 *)val; 179 mask = UINT_MAX; 180 break; 181 case 8: 182 default: 183 data = *(u64 *)val; 184 mask = ULONG_MAX; 185 break; 186 } 187 188 offset = (addr - s->pch_pic_base) & 7; 189 mask = mask << (offset * 8); 190 data = data << (offset * 8); 191 offset = (addr - s->pch_pic_base) - offset; 192 193 spin_lock(&s->lock); 194 switch (offset) { 195 case PCH_PIC_MASK_START: 196 old = s->mask; 197 s->mask = (old & ~mask) | data; 198 if (old & ~data) 199 pch_pic_update_batch_irqs(s, old & ~data, 1); 200 if (~old & data) 201 pch_pic_update_batch_irqs(s, ~old & data, 0); 202 break; 203 case PCH_PIC_HTMSI_EN_START: 204 s->htmsi_en = (s->htmsi_en & ~mask) | data; 205 break; 206 case PCH_PIC_EDGE_START: 207 s->edge = (s->edge & ~mask) | data; 208 break; 209 case PCH_PIC_POLARITY_START: 210 s->polarity = (s->polarity & ~mask) | data; 211 break; 212 case PCH_PIC_CLEAR_START: 213 old = s->irr & s->edge & data; 214 if (old) { 215 s->irr &= ~old; 216 pch_pic_update_batch_irqs(s, old, 0); 217 } 218 break; 219 case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END: 220 ptemp = s->htmsi_vector + (offset - PCH_PIC_HTMSI_VEC_START); 221 *(u64 *)ptemp = (*(u64 *)ptemp & ~mask) | data; 222 break; 223 /* Not implemented */ 224 case PCH_PIC_AUTO_CTRL0_START: 225 case PCH_PIC_AUTO_CTRL1_START: 226 case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END: 227 break; 228 default: 229 ret = -EINVAL; 230 break; 231 } 232 spin_unlock(&s->lock); 233 234 return ret; 235 } 236 237 static int kvm_pch_pic_write(struct kvm_vcpu *vcpu, 238 struct kvm_io_device *dev, 239 gpa_t addr, int len, const void *val) 240 { 241 int ret; 242 struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic; 243 244 if (!s) { 245 kvm_err("%s: pch pic irqchip not valid!\n", __func__); 246 return -EINVAL; 247 } 248 249 if (addr & (len - 1)) { 250 kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len); 251 return -EINVAL; 252 } 253 254 /* statistics of pch pic writing */ 255 vcpu->stat.pch_pic_write_exits++; 256 ret = loongarch_pch_pic_write(s, addr, len, val); 257 258 return ret; 259 } 260 261 static const struct kvm_io_device_ops kvm_pch_pic_ops = { 262 .read = kvm_pch_pic_read, 263 .write = kvm_pch_pic_write, 264 }; 265 266 static int kvm_pch_pic_init(struct kvm_device *dev, u64 addr) 267 { 268 int ret; 269 struct kvm *kvm = dev->kvm; 270 struct kvm_io_device *device; 271 struct loongarch_pch_pic *s = dev->kvm->arch.pch_pic; 272 273 s->pch_pic_base = addr; 274 device = &s->device; 275 /* init device by pch pic writing and reading ops */ 276 kvm_iodevice_init(device, &kvm_pch_pic_ops); 277 mutex_lock(&kvm->slots_lock); 278 /* register pch pic device */ 279 ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, addr, PCH_PIC_SIZE, device); 280 mutex_unlock(&kvm->slots_lock); 281 282 return (ret < 0) ? -EFAULT : 0; 283 } 284 285 /* used by user space to get or set pch pic registers */ 286 static int kvm_pch_pic_regs_access(struct kvm_device *dev, 287 struct kvm_device_attr *attr, 288 bool is_write) 289 { 290 char buf[8]; 291 int addr, offset, len = 8, ret = 0; 292 void __user *data; 293 void *p = NULL; 294 struct loongarch_pch_pic *s; 295 296 s = dev->kvm->arch.pch_pic; 297 addr = attr->attr; 298 data = (void __user *)attr->addr; 299 300 /* get pointer to pch pic register by addr */ 301 switch (addr) { 302 case PCH_PIC_MASK_START: 303 p = &s->mask; 304 break; 305 case PCH_PIC_HTMSI_EN_START: 306 p = &s->htmsi_en; 307 break; 308 case PCH_PIC_EDGE_START: 309 p = &s->edge; 310 break; 311 case PCH_PIC_AUTO_CTRL0_START: 312 p = &s->auto_ctrl0; 313 break; 314 case PCH_PIC_AUTO_CTRL1_START: 315 p = &s->auto_ctrl1; 316 break; 317 case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END: 318 offset = addr - PCH_PIC_ROUTE_ENTRY_START; 319 p = &s->route_entry[offset]; 320 len = 1; 321 break; 322 case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END: 323 offset = addr - PCH_PIC_HTMSI_VEC_START; 324 p = &s->htmsi_vector[offset]; 325 len = 1; 326 break; 327 case PCH_PIC_INT_IRR_START: 328 p = &s->irr; 329 break; 330 case PCH_PIC_INT_ISR_START: 331 p = &s->isr; 332 break; 333 case PCH_PIC_POLARITY_START: 334 p = &s->polarity; 335 break; 336 default: 337 return -EINVAL; 338 } 339 340 if (is_write) { 341 if (copy_from_user(buf, data, len)) 342 return -EFAULT; 343 } 344 345 spin_lock(&s->lock); 346 if (is_write) 347 memcpy(p, buf, len); 348 else 349 memcpy(buf, p, len); 350 spin_unlock(&s->lock); 351 352 if (!is_write) { 353 if (copy_to_user(data, buf, len)) 354 return -EFAULT; 355 } 356 357 return ret; 358 } 359 360 static int kvm_pch_pic_get_attr(struct kvm_device *dev, 361 struct kvm_device_attr *attr) 362 { 363 switch (attr->group) { 364 case KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS: 365 return kvm_pch_pic_regs_access(dev, attr, false); 366 default: 367 return -EINVAL; 368 } 369 } 370 371 static int kvm_pch_pic_set_attr(struct kvm_device *dev, 372 struct kvm_device_attr *attr) 373 { 374 u64 addr; 375 void __user *uaddr = (void __user *)(long)attr->addr; 376 377 switch (attr->group) { 378 case KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL: 379 switch (attr->attr) { 380 case KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT: 381 if (copy_from_user(&addr, uaddr, sizeof(addr))) 382 return -EFAULT; 383 384 if (!dev->kvm->arch.pch_pic) { 385 kvm_err("%s: please create pch_pic irqchip first!\n", __func__); 386 return -ENODEV; 387 } 388 389 return kvm_pch_pic_init(dev, addr); 390 default: 391 kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group, 392 attr->attr); 393 return -EINVAL; 394 } 395 case KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS: 396 return kvm_pch_pic_regs_access(dev, attr, true); 397 default: 398 return -EINVAL; 399 } 400 } 401 402 static int kvm_setup_default_irq_routing(struct kvm *kvm) 403 { 404 int i, ret; 405 u32 nr = KVM_IRQCHIP_NUM_PINS; 406 struct kvm_irq_routing_entry *entries; 407 408 entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL); 409 if (!entries) 410 return -ENOMEM; 411 412 for (i = 0; i < nr; i++) { 413 entries[i].gsi = i; 414 entries[i].type = KVM_IRQ_ROUTING_IRQCHIP; 415 entries[i].u.irqchip.irqchip = 0; 416 entries[i].u.irqchip.pin = i; 417 } 418 ret = kvm_set_irq_routing(kvm, entries, nr, 0); 419 kfree(entries); 420 421 return ret; 422 } 423 424 static int kvm_pch_pic_create(struct kvm_device *dev, u32 type) 425 { 426 int i, ret, irq_num; 427 struct kvm *kvm = dev->kvm; 428 struct loongarch_pch_pic *s; 429 430 /* pch pic should not has been created */ 431 if (kvm->arch.pch_pic) 432 return -EINVAL; 433 434 ret = kvm_setup_default_irq_routing(kvm); 435 if (ret) 436 return -ENOMEM; 437 438 s = kzalloc(sizeof(struct loongarch_pch_pic), GFP_KERNEL); 439 if (!s) 440 return -ENOMEM; 441 442 /* 443 * Interrupt controller identification register 1 444 * Bit 24-31 Interrupt Controller ID 445 * Interrupt controller identification register 2 446 * Bit 0-7 Interrupt Controller version number 447 * Bit 16-23 The number of interrupt sources supported 448 */ 449 irq_num = 32; 450 s->mask = -1UL; 451 s->id.desc.id = PCH_PIC_INT_ID_VAL; 452 s->id.desc.version = PCH_PIC_INT_ID_VER; 453 s->id.desc.irq_num = irq_num - 1; 454 for (i = 0; i < irq_num; i++) { 455 s->route_entry[i] = 1; 456 s->htmsi_vector[i] = i; 457 } 458 spin_lock_init(&s->lock); 459 s->kvm = kvm; 460 kvm->arch.pch_pic = s; 461 462 return 0; 463 } 464 465 static void kvm_pch_pic_destroy(struct kvm_device *dev) 466 { 467 struct kvm *kvm; 468 struct loongarch_pch_pic *s; 469 470 if (!dev || !dev->kvm || !dev->kvm->arch.pch_pic) 471 return; 472 473 kvm = dev->kvm; 474 s = kvm->arch.pch_pic; 475 /* unregister pch pic device and free it's memory */ 476 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &s->device); 477 kfree(s); 478 } 479 480 static struct kvm_device_ops kvm_pch_pic_dev_ops = { 481 .name = "kvm-loongarch-pch-pic", 482 .create = kvm_pch_pic_create, 483 .destroy = kvm_pch_pic_destroy, 484 .set_attr = kvm_pch_pic_set_attr, 485 .get_attr = kvm_pch_pic_get_attr, 486 }; 487 488 int kvm_loongarch_register_pch_pic_device(void) 489 { 490 return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC); 491 } 492