1bc5ad3f3SBenjamin Herrenschmidt /* 2bc5ad3f3SBenjamin Herrenschmidt * Copyright 2012 Michael Ellerman, IBM Corporation. 3bc5ad3f3SBenjamin Herrenschmidt * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation. 4bc5ad3f3SBenjamin Herrenschmidt * 5bc5ad3f3SBenjamin Herrenschmidt * This program is free software; you can redistribute it and/or modify 6bc5ad3f3SBenjamin Herrenschmidt * it under the terms of the GNU General Public License, version 2, as 7bc5ad3f3SBenjamin Herrenschmidt * published by the Free Software Foundation. 8bc5ad3f3SBenjamin Herrenschmidt */ 9bc5ad3f3SBenjamin Herrenschmidt 10bc5ad3f3SBenjamin Herrenschmidt #include <linux/kernel.h> 11bc5ad3f3SBenjamin Herrenschmidt #include <linux/kvm_host.h> 12bc5ad3f3SBenjamin Herrenschmidt #include <linux/err.h> 13bc5ad3f3SBenjamin Herrenschmidt #include <linux/gfp.h> 14bc5ad3f3SBenjamin Herrenschmidt 15bc5ad3f3SBenjamin Herrenschmidt #include <asm/uaccess.h> 16bc5ad3f3SBenjamin Herrenschmidt #include <asm/kvm_book3s.h> 17bc5ad3f3SBenjamin Herrenschmidt #include <asm/kvm_ppc.h> 18bc5ad3f3SBenjamin Herrenschmidt #include <asm/hvcall.h> 19bc5ad3f3SBenjamin Herrenschmidt #include <asm/xics.h> 20bc5ad3f3SBenjamin Herrenschmidt #include <asm/debug.h> 21bc5ad3f3SBenjamin Herrenschmidt 22bc5ad3f3SBenjamin Herrenschmidt #include <linux/debugfs.h> 23bc5ad3f3SBenjamin Herrenschmidt #include <linux/seq_file.h> 24bc5ad3f3SBenjamin Herrenschmidt 25bc5ad3f3SBenjamin Herrenschmidt #include "book3s_xics.h" 26bc5ad3f3SBenjamin Herrenschmidt 27bc5ad3f3SBenjamin Herrenschmidt #if 1 28bc5ad3f3SBenjamin Herrenschmidt #define XICS_DBG(fmt...) do { } while (0) 29bc5ad3f3SBenjamin Herrenschmidt #else 30bc5ad3f3SBenjamin Herrenschmidt #define XICS_DBG(fmt...) trace_printk(fmt) 31bc5ad3f3SBenjamin Herrenschmidt #endif 32bc5ad3f3SBenjamin Herrenschmidt 33e7d26f28SBenjamin Herrenschmidt #define ENABLE_REALMODE true 34e7d26f28SBenjamin Herrenschmidt #define DEBUG_REALMODE false 35e7d26f28SBenjamin Herrenschmidt 36bc5ad3f3SBenjamin Herrenschmidt /* 37bc5ad3f3SBenjamin Herrenschmidt * LOCKING 38bc5ad3f3SBenjamin Herrenschmidt * ======= 39bc5ad3f3SBenjamin Herrenschmidt * 40bc5ad3f3SBenjamin Herrenschmidt * Each ICS has a mutex protecting the information about the IRQ 41bc5ad3f3SBenjamin Herrenschmidt * sources and avoiding simultaneous deliveries if the same interrupt. 42bc5ad3f3SBenjamin Herrenschmidt * 43bc5ad3f3SBenjamin Herrenschmidt * ICP operations are done via a single compare & swap transaction 44bc5ad3f3SBenjamin Herrenschmidt * (most ICP state fits in the union kvmppc_icp_state) 45bc5ad3f3SBenjamin Herrenschmidt */ 46bc5ad3f3SBenjamin Herrenschmidt 47bc5ad3f3SBenjamin Herrenschmidt /* 48bc5ad3f3SBenjamin Herrenschmidt * TODO 49bc5ad3f3SBenjamin Herrenschmidt * ==== 50bc5ad3f3SBenjamin Herrenschmidt * 51bc5ad3f3SBenjamin Herrenschmidt * - To speed up resends, keep a bitmap of "resend" set bits in the 52bc5ad3f3SBenjamin Herrenschmidt * ICS 53bc5ad3f3SBenjamin Herrenschmidt * 54bc5ad3f3SBenjamin Herrenschmidt * - Speed up server# -> ICP lookup (array ? hash table ?) 55bc5ad3f3SBenjamin Herrenschmidt * 56bc5ad3f3SBenjamin Herrenschmidt * - Make ICS lockless as well, or at least a per-interrupt lock or hashed 57bc5ad3f3SBenjamin Herrenschmidt * locks array to improve scalability 58bc5ad3f3SBenjamin Herrenschmidt * 59bc5ad3f3SBenjamin Herrenschmidt * - ioctl's to save/restore the entire state for snapshot & migration 60bc5ad3f3SBenjamin Herrenschmidt */ 61bc5ad3f3SBenjamin Herrenschmidt 62bc5ad3f3SBenjamin Herrenschmidt /* -- ICS routines -- */ 63bc5ad3f3SBenjamin Herrenschmidt 64bc5ad3f3SBenjamin Herrenschmidt static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, 65bc5ad3f3SBenjamin Herrenschmidt u32 new_irq); 66bc5ad3f3SBenjamin Herrenschmidt 67bc5ad3f3SBenjamin Herrenschmidt static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) 68bc5ad3f3SBenjamin Herrenschmidt { 69bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state; 70bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 71bc5ad3f3SBenjamin Herrenschmidt u16 src; 72bc5ad3f3SBenjamin Herrenschmidt 73bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("ics deliver %#x (level: %d)\n", irq, level); 74bc5ad3f3SBenjamin Herrenschmidt 75bc5ad3f3SBenjamin Herrenschmidt ics = kvmppc_xics_find_ics(xics, irq, &src); 76bc5ad3f3SBenjamin Herrenschmidt if (!ics) { 77bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("ics_deliver_irq: IRQ 0x%06x not found !\n", irq); 78bc5ad3f3SBenjamin Herrenschmidt return -EINVAL; 79bc5ad3f3SBenjamin Herrenschmidt } 80bc5ad3f3SBenjamin Herrenschmidt state = &ics->irq_state[src]; 81bc5ad3f3SBenjamin Herrenschmidt if (!state->exists) 82bc5ad3f3SBenjamin Herrenschmidt return -EINVAL; 83bc5ad3f3SBenjamin Herrenschmidt 84bc5ad3f3SBenjamin Herrenschmidt /* 85bc5ad3f3SBenjamin Herrenschmidt * We set state->asserted locklessly. This should be fine as 86bc5ad3f3SBenjamin Herrenschmidt * we are the only setter, thus concurrent access is undefined 87bc5ad3f3SBenjamin Herrenschmidt * to begin with. 88bc5ad3f3SBenjamin Herrenschmidt */ 89bc5ad3f3SBenjamin Herrenschmidt if (level == KVM_INTERRUPT_SET_LEVEL) 90bc5ad3f3SBenjamin Herrenschmidt state->asserted = 1; 91bc5ad3f3SBenjamin Herrenschmidt else if (level == KVM_INTERRUPT_UNSET) { 92bc5ad3f3SBenjamin Herrenschmidt state->asserted = 0; 93bc5ad3f3SBenjamin Herrenschmidt return 0; 94bc5ad3f3SBenjamin Herrenschmidt } 95bc5ad3f3SBenjamin Herrenschmidt 96bc5ad3f3SBenjamin Herrenschmidt /* Attempt delivery */ 97bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, NULL, irq); 98bc5ad3f3SBenjamin Herrenschmidt 99bc5ad3f3SBenjamin Herrenschmidt return 0; 100bc5ad3f3SBenjamin Herrenschmidt } 101bc5ad3f3SBenjamin Herrenschmidt 102bc5ad3f3SBenjamin Herrenschmidt static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics, 103bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp) 104bc5ad3f3SBenjamin Herrenschmidt { 105bc5ad3f3SBenjamin Herrenschmidt int i; 106bc5ad3f3SBenjamin Herrenschmidt 107bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&ics->lock); 108bc5ad3f3SBenjamin Herrenschmidt 109bc5ad3f3SBenjamin Herrenschmidt for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { 110bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state = &ics->irq_state[i]; 111bc5ad3f3SBenjamin Herrenschmidt 112bc5ad3f3SBenjamin Herrenschmidt if (!state->resend) 113bc5ad3f3SBenjamin Herrenschmidt continue; 114bc5ad3f3SBenjamin Herrenschmidt 115bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("resend %#x prio %#x\n", state->number, 116bc5ad3f3SBenjamin Herrenschmidt state->priority); 117bc5ad3f3SBenjamin Herrenschmidt 118bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 119bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, state->number); 120bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&ics->lock); 121bc5ad3f3SBenjamin Herrenschmidt } 122bc5ad3f3SBenjamin Herrenschmidt 123bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 124bc5ad3f3SBenjamin Herrenschmidt } 125bc5ad3f3SBenjamin Herrenschmidt 126d19bd862SPaul Mackerras static bool write_xive(struct kvmppc_xics *xics, struct kvmppc_ics *ics, 127d19bd862SPaul Mackerras struct ics_irq_state *state, 128d19bd862SPaul Mackerras u32 server, u32 priority, u32 saved_priority) 129d19bd862SPaul Mackerras { 130d19bd862SPaul Mackerras bool deliver; 131d19bd862SPaul Mackerras 132d19bd862SPaul Mackerras mutex_lock(&ics->lock); 133d19bd862SPaul Mackerras 134d19bd862SPaul Mackerras state->server = server; 135d19bd862SPaul Mackerras state->priority = priority; 136d19bd862SPaul Mackerras state->saved_priority = saved_priority; 137d19bd862SPaul Mackerras deliver = false; 138d19bd862SPaul Mackerras if ((state->masked_pending || state->resend) && priority != MASKED) { 139d19bd862SPaul Mackerras state->masked_pending = 0; 140d19bd862SPaul Mackerras deliver = true; 141d19bd862SPaul Mackerras } 142d19bd862SPaul Mackerras 143d19bd862SPaul Mackerras mutex_unlock(&ics->lock); 144d19bd862SPaul Mackerras 145d19bd862SPaul Mackerras return deliver; 146d19bd862SPaul Mackerras } 147d19bd862SPaul Mackerras 148bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server, u32 priority) 149bc5ad3f3SBenjamin Herrenschmidt { 150bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = kvm->arch.xics; 151bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp; 152bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 153bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state; 154bc5ad3f3SBenjamin Herrenschmidt u16 src; 155bc5ad3f3SBenjamin Herrenschmidt 156bc5ad3f3SBenjamin Herrenschmidt if (!xics) 157bc5ad3f3SBenjamin Herrenschmidt return -ENODEV; 158bc5ad3f3SBenjamin Herrenschmidt 159bc5ad3f3SBenjamin Herrenschmidt ics = kvmppc_xics_find_ics(xics, irq, &src); 160bc5ad3f3SBenjamin Herrenschmidt if (!ics) 161bc5ad3f3SBenjamin Herrenschmidt return -EINVAL; 162bc5ad3f3SBenjamin Herrenschmidt state = &ics->irq_state[src]; 163bc5ad3f3SBenjamin Herrenschmidt 164bc5ad3f3SBenjamin Herrenschmidt icp = kvmppc_xics_find_server(kvm, server); 165bc5ad3f3SBenjamin Herrenschmidt if (!icp) 166bc5ad3f3SBenjamin Herrenschmidt return -EINVAL; 167bc5ad3f3SBenjamin Herrenschmidt 168bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("set_xive %#x server %#x prio %#x MP:%d RS:%d\n", 169bc5ad3f3SBenjamin Herrenschmidt irq, server, priority, 170bc5ad3f3SBenjamin Herrenschmidt state->masked_pending, state->resend); 171bc5ad3f3SBenjamin Herrenschmidt 172d19bd862SPaul Mackerras if (write_xive(xics, ics, state, server, priority, priority)) 173bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, irq); 174bc5ad3f3SBenjamin Herrenschmidt 175bc5ad3f3SBenjamin Herrenschmidt return 0; 176bc5ad3f3SBenjamin Herrenschmidt } 177bc5ad3f3SBenjamin Herrenschmidt 178bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server, u32 *priority) 179bc5ad3f3SBenjamin Herrenschmidt { 180bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = kvm->arch.xics; 181bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 182bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state; 183bc5ad3f3SBenjamin Herrenschmidt u16 src; 184bc5ad3f3SBenjamin Herrenschmidt 185bc5ad3f3SBenjamin Herrenschmidt if (!xics) 186bc5ad3f3SBenjamin Herrenschmidt return -ENODEV; 187bc5ad3f3SBenjamin Herrenschmidt 188bc5ad3f3SBenjamin Herrenschmidt ics = kvmppc_xics_find_ics(xics, irq, &src); 189bc5ad3f3SBenjamin Herrenschmidt if (!ics) 190bc5ad3f3SBenjamin Herrenschmidt return -EINVAL; 191bc5ad3f3SBenjamin Herrenschmidt state = &ics->irq_state[src]; 192bc5ad3f3SBenjamin Herrenschmidt 193bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&ics->lock); 194bc5ad3f3SBenjamin Herrenschmidt *server = state->server; 195bc5ad3f3SBenjamin Herrenschmidt *priority = state->priority; 196bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 197bc5ad3f3SBenjamin Herrenschmidt 198bc5ad3f3SBenjamin Herrenschmidt return 0; 199bc5ad3f3SBenjamin Herrenschmidt } 200bc5ad3f3SBenjamin Herrenschmidt 201d19bd862SPaul Mackerras int kvmppc_xics_int_on(struct kvm *kvm, u32 irq) 202d19bd862SPaul Mackerras { 203d19bd862SPaul Mackerras struct kvmppc_xics *xics = kvm->arch.xics; 204d19bd862SPaul Mackerras struct kvmppc_icp *icp; 205d19bd862SPaul Mackerras struct kvmppc_ics *ics; 206d19bd862SPaul Mackerras struct ics_irq_state *state; 207d19bd862SPaul Mackerras u16 src; 208d19bd862SPaul Mackerras 209d19bd862SPaul Mackerras if (!xics) 210d19bd862SPaul Mackerras return -ENODEV; 211d19bd862SPaul Mackerras 212d19bd862SPaul Mackerras ics = kvmppc_xics_find_ics(xics, irq, &src); 213d19bd862SPaul Mackerras if (!ics) 214d19bd862SPaul Mackerras return -EINVAL; 215d19bd862SPaul Mackerras state = &ics->irq_state[src]; 216d19bd862SPaul Mackerras 217d19bd862SPaul Mackerras icp = kvmppc_xics_find_server(kvm, state->server); 218d19bd862SPaul Mackerras if (!icp) 219d19bd862SPaul Mackerras return -EINVAL; 220d19bd862SPaul Mackerras 221d19bd862SPaul Mackerras if (write_xive(xics, ics, state, state->server, state->saved_priority, 222d19bd862SPaul Mackerras state->saved_priority)) 223d19bd862SPaul Mackerras icp_deliver_irq(xics, icp, irq); 224d19bd862SPaul Mackerras 225d19bd862SPaul Mackerras return 0; 226d19bd862SPaul Mackerras } 227d19bd862SPaul Mackerras 228d19bd862SPaul Mackerras int kvmppc_xics_int_off(struct kvm *kvm, u32 irq) 229d19bd862SPaul Mackerras { 230d19bd862SPaul Mackerras struct kvmppc_xics *xics = kvm->arch.xics; 231d19bd862SPaul Mackerras struct kvmppc_ics *ics; 232d19bd862SPaul Mackerras struct ics_irq_state *state; 233d19bd862SPaul Mackerras u16 src; 234d19bd862SPaul Mackerras 235d19bd862SPaul Mackerras if (!xics) 236d19bd862SPaul Mackerras return -ENODEV; 237d19bd862SPaul Mackerras 238d19bd862SPaul Mackerras ics = kvmppc_xics_find_ics(xics, irq, &src); 239d19bd862SPaul Mackerras if (!ics) 240d19bd862SPaul Mackerras return -EINVAL; 241d19bd862SPaul Mackerras state = &ics->irq_state[src]; 242d19bd862SPaul Mackerras 243d19bd862SPaul Mackerras write_xive(xics, ics, state, state->server, MASKED, state->priority); 244d19bd862SPaul Mackerras 245d19bd862SPaul Mackerras return 0; 246d19bd862SPaul Mackerras } 247d19bd862SPaul Mackerras 248bc5ad3f3SBenjamin Herrenschmidt /* -- ICP routines, including hcalls -- */ 249bc5ad3f3SBenjamin Herrenschmidt 250bc5ad3f3SBenjamin Herrenschmidt static inline bool icp_try_update(struct kvmppc_icp *icp, 251bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old, 252bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state new, 253bc5ad3f3SBenjamin Herrenschmidt bool change_self) 254bc5ad3f3SBenjamin Herrenschmidt { 255bc5ad3f3SBenjamin Herrenschmidt bool success; 256bc5ad3f3SBenjamin Herrenschmidt 257bc5ad3f3SBenjamin Herrenschmidt /* Calculate new output value */ 258bc5ad3f3SBenjamin Herrenschmidt new.out_ee = (new.xisr && (new.pending_pri < new.cppr)); 259bc5ad3f3SBenjamin Herrenschmidt 260bc5ad3f3SBenjamin Herrenschmidt /* Attempt atomic update */ 261bc5ad3f3SBenjamin Herrenschmidt success = cmpxchg64(&icp->state.raw, old.raw, new.raw) == old.raw; 262bc5ad3f3SBenjamin Herrenschmidt if (!success) 263bc5ad3f3SBenjamin Herrenschmidt goto bail; 264bc5ad3f3SBenjamin Herrenschmidt 265bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("UPD [%04x] - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n", 266bc5ad3f3SBenjamin Herrenschmidt icp->server_num, 267bc5ad3f3SBenjamin Herrenschmidt old.cppr, old.mfrr, old.pending_pri, old.xisr, 268bc5ad3f3SBenjamin Herrenschmidt old.need_resend, old.out_ee); 269bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("UPD - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n", 270bc5ad3f3SBenjamin Herrenschmidt new.cppr, new.mfrr, new.pending_pri, new.xisr, 271bc5ad3f3SBenjamin Herrenschmidt new.need_resend, new.out_ee); 272bc5ad3f3SBenjamin Herrenschmidt /* 273bc5ad3f3SBenjamin Herrenschmidt * Check for output state update 274bc5ad3f3SBenjamin Herrenschmidt * 275bc5ad3f3SBenjamin Herrenschmidt * Note that this is racy since another processor could be updating 276bc5ad3f3SBenjamin Herrenschmidt * the state already. This is why we never clear the interrupt output 277bc5ad3f3SBenjamin Herrenschmidt * here, we only ever set it. The clear only happens prior to doing 278bc5ad3f3SBenjamin Herrenschmidt * an update and only by the processor itself. Currently we do it 279bc5ad3f3SBenjamin Herrenschmidt * in Accept (H_XIRR) and Up_Cppr (H_XPPR). 280bc5ad3f3SBenjamin Herrenschmidt * 281bc5ad3f3SBenjamin Herrenschmidt * We also do not try to figure out whether the EE state has changed, 282e7d26f28SBenjamin Herrenschmidt * we unconditionally set it if the new state calls for it. The reason 283e7d26f28SBenjamin Herrenschmidt * for that is that we opportunistically remove the pending interrupt 284e7d26f28SBenjamin Herrenschmidt * flag when raising CPPR, so we need to set it back here if an 285e7d26f28SBenjamin Herrenschmidt * interrupt is still pending. 286bc5ad3f3SBenjamin Herrenschmidt */ 287bc5ad3f3SBenjamin Herrenschmidt if (new.out_ee) { 288bc5ad3f3SBenjamin Herrenschmidt kvmppc_book3s_queue_irqprio(icp->vcpu, 289bc5ad3f3SBenjamin Herrenschmidt BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 290bc5ad3f3SBenjamin Herrenschmidt if (!change_self) 29154695c30SBenjamin Herrenschmidt kvmppc_fast_vcpu_kick(icp->vcpu); 292bc5ad3f3SBenjamin Herrenschmidt } 293bc5ad3f3SBenjamin Herrenschmidt bail: 294bc5ad3f3SBenjamin Herrenschmidt return success; 295bc5ad3f3SBenjamin Herrenschmidt } 296bc5ad3f3SBenjamin Herrenschmidt 297bc5ad3f3SBenjamin Herrenschmidt static void icp_check_resend(struct kvmppc_xics *xics, 298bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp) 299bc5ad3f3SBenjamin Herrenschmidt { 300bc5ad3f3SBenjamin Herrenschmidt u32 icsid; 301bc5ad3f3SBenjamin Herrenschmidt 302bc5ad3f3SBenjamin Herrenschmidt /* Order this load with the test for need_resend in the caller */ 303bc5ad3f3SBenjamin Herrenschmidt smp_rmb(); 304bc5ad3f3SBenjamin Herrenschmidt for_each_set_bit(icsid, icp->resend_map, xics->max_icsid + 1) { 305bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics = xics->ics[icsid]; 306bc5ad3f3SBenjamin Herrenschmidt 307bc5ad3f3SBenjamin Herrenschmidt if (!test_and_clear_bit(icsid, icp->resend_map)) 308bc5ad3f3SBenjamin Herrenschmidt continue; 309bc5ad3f3SBenjamin Herrenschmidt if (!ics) 310bc5ad3f3SBenjamin Herrenschmidt continue; 311bc5ad3f3SBenjamin Herrenschmidt ics_check_resend(xics, ics, icp); 312bc5ad3f3SBenjamin Herrenschmidt } 313bc5ad3f3SBenjamin Herrenschmidt } 314bc5ad3f3SBenjamin Herrenschmidt 315bc5ad3f3SBenjamin Herrenschmidt static bool icp_try_to_deliver(struct kvmppc_icp *icp, u32 irq, u8 priority, 316bc5ad3f3SBenjamin Herrenschmidt u32 *reject) 317bc5ad3f3SBenjamin Herrenschmidt { 318bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old_state, new_state; 319bc5ad3f3SBenjamin Herrenschmidt bool success; 320bc5ad3f3SBenjamin Herrenschmidt 321bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("try deliver %#x(P:%#x) to server %#x\n", irq, priority, 322bc5ad3f3SBenjamin Herrenschmidt icp->server_num); 323bc5ad3f3SBenjamin Herrenschmidt 324bc5ad3f3SBenjamin Herrenschmidt do { 325bc5ad3f3SBenjamin Herrenschmidt old_state = new_state = ACCESS_ONCE(icp->state); 326bc5ad3f3SBenjamin Herrenschmidt 327bc5ad3f3SBenjamin Herrenschmidt *reject = 0; 328bc5ad3f3SBenjamin Herrenschmidt 329bc5ad3f3SBenjamin Herrenschmidt /* See if we can deliver */ 330bc5ad3f3SBenjamin Herrenschmidt success = new_state.cppr > priority && 331bc5ad3f3SBenjamin Herrenschmidt new_state.mfrr > priority && 332bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri > priority; 333bc5ad3f3SBenjamin Herrenschmidt 334bc5ad3f3SBenjamin Herrenschmidt /* 335bc5ad3f3SBenjamin Herrenschmidt * If we can, check for a rejection and perform the 336bc5ad3f3SBenjamin Herrenschmidt * delivery 337bc5ad3f3SBenjamin Herrenschmidt */ 338bc5ad3f3SBenjamin Herrenschmidt if (success) { 339bc5ad3f3SBenjamin Herrenschmidt *reject = new_state.xisr; 340bc5ad3f3SBenjamin Herrenschmidt new_state.xisr = irq; 341bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri = priority; 342bc5ad3f3SBenjamin Herrenschmidt } else { 343bc5ad3f3SBenjamin Herrenschmidt /* 344bc5ad3f3SBenjamin Herrenschmidt * If we failed to deliver we set need_resend 345bc5ad3f3SBenjamin Herrenschmidt * so a subsequent CPPR state change causes us 346bc5ad3f3SBenjamin Herrenschmidt * to try a new delivery. 347bc5ad3f3SBenjamin Herrenschmidt */ 348bc5ad3f3SBenjamin Herrenschmidt new_state.need_resend = true; 349bc5ad3f3SBenjamin Herrenschmidt } 350bc5ad3f3SBenjamin Herrenschmidt 351bc5ad3f3SBenjamin Herrenschmidt } while (!icp_try_update(icp, old_state, new_state, false)); 352bc5ad3f3SBenjamin Herrenschmidt 353bc5ad3f3SBenjamin Herrenschmidt return success; 354bc5ad3f3SBenjamin Herrenschmidt } 355bc5ad3f3SBenjamin Herrenschmidt 356bc5ad3f3SBenjamin Herrenschmidt static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, 357bc5ad3f3SBenjamin Herrenschmidt u32 new_irq) 358bc5ad3f3SBenjamin Herrenschmidt { 359bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state; 360bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 361bc5ad3f3SBenjamin Herrenschmidt u32 reject; 362bc5ad3f3SBenjamin Herrenschmidt u16 src; 363bc5ad3f3SBenjamin Herrenschmidt 364bc5ad3f3SBenjamin Herrenschmidt /* 365bc5ad3f3SBenjamin Herrenschmidt * This is used both for initial delivery of an interrupt and 366bc5ad3f3SBenjamin Herrenschmidt * for subsequent rejection. 367bc5ad3f3SBenjamin Herrenschmidt * 368bc5ad3f3SBenjamin Herrenschmidt * Rejection can be racy vs. resends. We have evaluated the 369bc5ad3f3SBenjamin Herrenschmidt * rejection in an atomic ICP transaction which is now complete, 370bc5ad3f3SBenjamin Herrenschmidt * so potentially the ICP can already accept the interrupt again. 371bc5ad3f3SBenjamin Herrenschmidt * 372bc5ad3f3SBenjamin Herrenschmidt * So we need to retry the delivery. Essentially the reject path 373bc5ad3f3SBenjamin Herrenschmidt * boils down to a failed delivery. Always. 374bc5ad3f3SBenjamin Herrenschmidt * 375bc5ad3f3SBenjamin Herrenschmidt * Now the interrupt could also have moved to a different target, 376bc5ad3f3SBenjamin Herrenschmidt * thus we may need to re-do the ICP lookup as well 377bc5ad3f3SBenjamin Herrenschmidt */ 378bc5ad3f3SBenjamin Herrenschmidt 379bc5ad3f3SBenjamin Herrenschmidt again: 380bc5ad3f3SBenjamin Herrenschmidt /* Get the ICS state and lock it */ 381bc5ad3f3SBenjamin Herrenschmidt ics = kvmppc_xics_find_ics(xics, new_irq, &src); 382bc5ad3f3SBenjamin Herrenschmidt if (!ics) { 383bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("icp_deliver_irq: IRQ 0x%06x not found !\n", new_irq); 384bc5ad3f3SBenjamin Herrenschmidt return; 385bc5ad3f3SBenjamin Herrenschmidt } 386bc5ad3f3SBenjamin Herrenschmidt state = &ics->irq_state[src]; 387bc5ad3f3SBenjamin Herrenschmidt 388bc5ad3f3SBenjamin Herrenschmidt /* Get a lock on the ICS */ 389bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&ics->lock); 390bc5ad3f3SBenjamin Herrenschmidt 391bc5ad3f3SBenjamin Herrenschmidt /* Get our server */ 392bc5ad3f3SBenjamin Herrenschmidt if (!icp || state->server != icp->server_num) { 393bc5ad3f3SBenjamin Herrenschmidt icp = kvmppc_xics_find_server(xics->kvm, state->server); 394bc5ad3f3SBenjamin Herrenschmidt if (!icp) { 395bc5ad3f3SBenjamin Herrenschmidt pr_warn("icp_deliver_irq: IRQ 0x%06x server 0x%x not found !\n", 396bc5ad3f3SBenjamin Herrenschmidt new_irq, state->server); 397bc5ad3f3SBenjamin Herrenschmidt goto out; 398bc5ad3f3SBenjamin Herrenschmidt } 399bc5ad3f3SBenjamin Herrenschmidt } 400bc5ad3f3SBenjamin Herrenschmidt 401bc5ad3f3SBenjamin Herrenschmidt /* Clear the resend bit of that interrupt */ 402bc5ad3f3SBenjamin Herrenschmidt state->resend = 0; 403bc5ad3f3SBenjamin Herrenschmidt 404bc5ad3f3SBenjamin Herrenschmidt /* 405bc5ad3f3SBenjamin Herrenschmidt * If masked, bail out 406bc5ad3f3SBenjamin Herrenschmidt * 407bc5ad3f3SBenjamin Herrenschmidt * Note: PAPR doesn't mention anything about masked pending 408bc5ad3f3SBenjamin Herrenschmidt * when doing a resend, only when doing a delivery. 409bc5ad3f3SBenjamin Herrenschmidt * 410bc5ad3f3SBenjamin Herrenschmidt * However that would have the effect of losing a masked 411bc5ad3f3SBenjamin Herrenschmidt * interrupt that was rejected and isn't consistent with 412bc5ad3f3SBenjamin Herrenschmidt * the whole masked_pending business which is about not 413bc5ad3f3SBenjamin Herrenschmidt * losing interrupts that occur while masked. 414bc5ad3f3SBenjamin Herrenschmidt * 415bc5ad3f3SBenjamin Herrenschmidt * I don't differenciate normal deliveries and resends, this 416bc5ad3f3SBenjamin Herrenschmidt * implementation will differ from PAPR and not lose such 417bc5ad3f3SBenjamin Herrenschmidt * interrupts. 418bc5ad3f3SBenjamin Herrenschmidt */ 419bc5ad3f3SBenjamin Herrenschmidt if (state->priority == MASKED) { 420bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("irq %#x masked pending\n", new_irq); 421bc5ad3f3SBenjamin Herrenschmidt state->masked_pending = 1; 422bc5ad3f3SBenjamin Herrenschmidt goto out; 423bc5ad3f3SBenjamin Herrenschmidt } 424bc5ad3f3SBenjamin Herrenschmidt 425bc5ad3f3SBenjamin Herrenschmidt /* 426bc5ad3f3SBenjamin Herrenschmidt * Try the delivery, this will set the need_resend flag 427bc5ad3f3SBenjamin Herrenschmidt * in the ICP as part of the atomic transaction if the 428bc5ad3f3SBenjamin Herrenschmidt * delivery is not possible. 429bc5ad3f3SBenjamin Herrenschmidt * 430bc5ad3f3SBenjamin Herrenschmidt * Note that if successful, the new delivery might have itself 431bc5ad3f3SBenjamin Herrenschmidt * rejected an interrupt that was "delivered" before we took the 432bc5ad3f3SBenjamin Herrenschmidt * icp mutex. 433bc5ad3f3SBenjamin Herrenschmidt * 434bc5ad3f3SBenjamin Herrenschmidt * In this case we do the whole sequence all over again for the 435bc5ad3f3SBenjamin Herrenschmidt * new guy. We cannot assume that the rejected interrupt is less 436bc5ad3f3SBenjamin Herrenschmidt * favored than the new one, and thus doesn't need to be delivered, 437bc5ad3f3SBenjamin Herrenschmidt * because by the time we exit icp_try_to_deliver() the target 438bc5ad3f3SBenjamin Herrenschmidt * processor may well have alrady consumed & completed it, and thus 439bc5ad3f3SBenjamin Herrenschmidt * the rejected interrupt might actually be already acceptable. 440bc5ad3f3SBenjamin Herrenschmidt */ 441bc5ad3f3SBenjamin Herrenschmidt if (icp_try_to_deliver(icp, new_irq, state->priority, &reject)) { 442bc5ad3f3SBenjamin Herrenschmidt /* 443bc5ad3f3SBenjamin Herrenschmidt * Delivery was successful, did we reject somebody else ? 444bc5ad3f3SBenjamin Herrenschmidt */ 445bc5ad3f3SBenjamin Herrenschmidt if (reject && reject != XICS_IPI) { 446bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 447bc5ad3f3SBenjamin Herrenschmidt new_irq = reject; 448bc5ad3f3SBenjamin Herrenschmidt goto again; 449bc5ad3f3SBenjamin Herrenschmidt } 450bc5ad3f3SBenjamin Herrenschmidt } else { 451bc5ad3f3SBenjamin Herrenschmidt /* 452bc5ad3f3SBenjamin Herrenschmidt * We failed to deliver the interrupt we need to set the 453bc5ad3f3SBenjamin Herrenschmidt * resend map bit and mark the ICS state as needing a resend 454bc5ad3f3SBenjamin Herrenschmidt */ 455bc5ad3f3SBenjamin Herrenschmidt set_bit(ics->icsid, icp->resend_map); 456bc5ad3f3SBenjamin Herrenschmidt state->resend = 1; 457bc5ad3f3SBenjamin Herrenschmidt 458bc5ad3f3SBenjamin Herrenschmidt /* 459bc5ad3f3SBenjamin Herrenschmidt * If the need_resend flag got cleared in the ICP some time 460bc5ad3f3SBenjamin Herrenschmidt * between icp_try_to_deliver() atomic update and now, then 461bc5ad3f3SBenjamin Herrenschmidt * we know it might have missed the resend_map bit. So we 462bc5ad3f3SBenjamin Herrenschmidt * retry 463bc5ad3f3SBenjamin Herrenschmidt */ 464bc5ad3f3SBenjamin Herrenschmidt smp_mb(); 465bc5ad3f3SBenjamin Herrenschmidt if (!icp->state.need_resend) { 466bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 467bc5ad3f3SBenjamin Herrenschmidt goto again; 468bc5ad3f3SBenjamin Herrenschmidt } 469bc5ad3f3SBenjamin Herrenschmidt } 470bc5ad3f3SBenjamin Herrenschmidt out: 471bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 472bc5ad3f3SBenjamin Herrenschmidt } 473bc5ad3f3SBenjamin Herrenschmidt 474bc5ad3f3SBenjamin Herrenschmidt static void icp_down_cppr(struct kvmppc_xics *xics, struct kvmppc_icp *icp, 475bc5ad3f3SBenjamin Herrenschmidt u8 new_cppr) 476bc5ad3f3SBenjamin Herrenschmidt { 477bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old_state, new_state; 478bc5ad3f3SBenjamin Herrenschmidt bool resend; 479bc5ad3f3SBenjamin Herrenschmidt 480bc5ad3f3SBenjamin Herrenschmidt /* 481bc5ad3f3SBenjamin Herrenschmidt * This handles several related states in one operation: 482bc5ad3f3SBenjamin Herrenschmidt * 483bc5ad3f3SBenjamin Herrenschmidt * ICP State: Down_CPPR 484bc5ad3f3SBenjamin Herrenschmidt * 485bc5ad3f3SBenjamin Herrenschmidt * Load CPPR with new value and if the XISR is 0 486bc5ad3f3SBenjamin Herrenschmidt * then check for resends: 487bc5ad3f3SBenjamin Herrenschmidt * 488bc5ad3f3SBenjamin Herrenschmidt * ICP State: Resend 489bc5ad3f3SBenjamin Herrenschmidt * 490bc5ad3f3SBenjamin Herrenschmidt * If MFRR is more favored than CPPR, check for IPIs 491bc5ad3f3SBenjamin Herrenschmidt * and notify ICS of a potential resend. This is done 492bc5ad3f3SBenjamin Herrenschmidt * asynchronously (when used in real mode, we will have 493bc5ad3f3SBenjamin Herrenschmidt * to exit here). 494bc5ad3f3SBenjamin Herrenschmidt * 495bc5ad3f3SBenjamin Herrenschmidt * We do not handle the complete Check_IPI as documented 496bc5ad3f3SBenjamin Herrenschmidt * here. In the PAPR, this state will be used for both 497bc5ad3f3SBenjamin Herrenschmidt * Set_MFRR and Down_CPPR. However, we know that we aren't 498bc5ad3f3SBenjamin Herrenschmidt * changing the MFRR state here so we don't need to handle 499bc5ad3f3SBenjamin Herrenschmidt * the case of an MFRR causing a reject of a pending irq, 500bc5ad3f3SBenjamin Herrenschmidt * this will have been handled when the MFRR was set in the 501bc5ad3f3SBenjamin Herrenschmidt * first place. 502bc5ad3f3SBenjamin Herrenschmidt * 503bc5ad3f3SBenjamin Herrenschmidt * Thus we don't have to handle rejects, only resends. 504bc5ad3f3SBenjamin Herrenschmidt * 505bc5ad3f3SBenjamin Herrenschmidt * When implementing real mode for HV KVM, resend will lead to 506bc5ad3f3SBenjamin Herrenschmidt * a H_TOO_HARD return and the whole transaction will be handled 507bc5ad3f3SBenjamin Herrenschmidt * in virtual mode. 508bc5ad3f3SBenjamin Herrenschmidt */ 509bc5ad3f3SBenjamin Herrenschmidt do { 510bc5ad3f3SBenjamin Herrenschmidt old_state = new_state = ACCESS_ONCE(icp->state); 511bc5ad3f3SBenjamin Herrenschmidt 512bc5ad3f3SBenjamin Herrenschmidt /* Down_CPPR */ 513bc5ad3f3SBenjamin Herrenschmidt new_state.cppr = new_cppr; 514bc5ad3f3SBenjamin Herrenschmidt 515bc5ad3f3SBenjamin Herrenschmidt /* 516bc5ad3f3SBenjamin Herrenschmidt * Cut down Resend / Check_IPI / IPI 517bc5ad3f3SBenjamin Herrenschmidt * 518bc5ad3f3SBenjamin Herrenschmidt * The logic is that we cannot have a pending interrupt 519bc5ad3f3SBenjamin Herrenschmidt * trumped by an IPI at this point (see above), so we 520bc5ad3f3SBenjamin Herrenschmidt * know that either the pending interrupt is already an 521bc5ad3f3SBenjamin Herrenschmidt * IPI (in which case we don't care to override it) or 522bc5ad3f3SBenjamin Herrenschmidt * it's either more favored than us or non existent 523bc5ad3f3SBenjamin Herrenschmidt */ 524bc5ad3f3SBenjamin Herrenschmidt if (new_state.mfrr < new_cppr && 525bc5ad3f3SBenjamin Herrenschmidt new_state.mfrr <= new_state.pending_pri) { 526bc5ad3f3SBenjamin Herrenschmidt WARN_ON(new_state.xisr != XICS_IPI && 527bc5ad3f3SBenjamin Herrenschmidt new_state.xisr != 0); 528bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri = new_state.mfrr; 529bc5ad3f3SBenjamin Herrenschmidt new_state.xisr = XICS_IPI; 530bc5ad3f3SBenjamin Herrenschmidt } 531bc5ad3f3SBenjamin Herrenschmidt 532bc5ad3f3SBenjamin Herrenschmidt /* Latch/clear resend bit */ 533bc5ad3f3SBenjamin Herrenschmidt resend = new_state.need_resend; 534bc5ad3f3SBenjamin Herrenschmidt new_state.need_resend = 0; 535bc5ad3f3SBenjamin Herrenschmidt 536bc5ad3f3SBenjamin Herrenschmidt } while (!icp_try_update(icp, old_state, new_state, true)); 537bc5ad3f3SBenjamin Herrenschmidt 538bc5ad3f3SBenjamin Herrenschmidt /* 539bc5ad3f3SBenjamin Herrenschmidt * Now handle resend checks. Those are asynchronous to the ICP 540bc5ad3f3SBenjamin Herrenschmidt * state update in HW (ie bus transactions) so we can handle them 541bc5ad3f3SBenjamin Herrenschmidt * separately here too 542bc5ad3f3SBenjamin Herrenschmidt */ 543bc5ad3f3SBenjamin Herrenschmidt if (resend) 544bc5ad3f3SBenjamin Herrenschmidt icp_check_resend(xics, icp); 545bc5ad3f3SBenjamin Herrenschmidt } 546bc5ad3f3SBenjamin Herrenschmidt 547e7d26f28SBenjamin Herrenschmidt static noinline unsigned long kvmppc_h_xirr(struct kvm_vcpu *vcpu) 548bc5ad3f3SBenjamin Herrenschmidt { 549bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old_state, new_state; 550bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp = vcpu->arch.icp; 551bc5ad3f3SBenjamin Herrenschmidt u32 xirr; 552bc5ad3f3SBenjamin Herrenschmidt 553bc5ad3f3SBenjamin Herrenschmidt /* First, remove EE from the processor */ 554bc5ad3f3SBenjamin Herrenschmidt kvmppc_book3s_dequeue_irqprio(icp->vcpu, 555bc5ad3f3SBenjamin Herrenschmidt BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 556bc5ad3f3SBenjamin Herrenschmidt 557bc5ad3f3SBenjamin Herrenschmidt /* 558bc5ad3f3SBenjamin Herrenschmidt * ICP State: Accept_Interrupt 559bc5ad3f3SBenjamin Herrenschmidt * 560bc5ad3f3SBenjamin Herrenschmidt * Return the pending interrupt (if any) along with the 561bc5ad3f3SBenjamin Herrenschmidt * current CPPR, then clear the XISR & set CPPR to the 562bc5ad3f3SBenjamin Herrenschmidt * pending priority 563bc5ad3f3SBenjamin Herrenschmidt */ 564bc5ad3f3SBenjamin Herrenschmidt do { 565bc5ad3f3SBenjamin Herrenschmidt old_state = new_state = ACCESS_ONCE(icp->state); 566bc5ad3f3SBenjamin Herrenschmidt 567bc5ad3f3SBenjamin Herrenschmidt xirr = old_state.xisr | (((u32)old_state.cppr) << 24); 568bc5ad3f3SBenjamin Herrenschmidt if (!old_state.xisr) 569bc5ad3f3SBenjamin Herrenschmidt break; 570bc5ad3f3SBenjamin Herrenschmidt new_state.cppr = new_state.pending_pri; 571bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri = 0xff; 572bc5ad3f3SBenjamin Herrenschmidt new_state.xisr = 0; 573bc5ad3f3SBenjamin Herrenschmidt 574bc5ad3f3SBenjamin Herrenschmidt } while (!icp_try_update(icp, old_state, new_state, true)); 575bc5ad3f3SBenjamin Herrenschmidt 576bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("h_xirr vcpu %d xirr %#x\n", vcpu->vcpu_id, xirr); 577bc5ad3f3SBenjamin Herrenschmidt 578bc5ad3f3SBenjamin Herrenschmidt return xirr; 579bc5ad3f3SBenjamin Herrenschmidt } 580bc5ad3f3SBenjamin Herrenschmidt 581e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, 582bc5ad3f3SBenjamin Herrenschmidt unsigned long mfrr) 583bc5ad3f3SBenjamin Herrenschmidt { 584bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old_state, new_state; 585bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 586bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp; 587bc5ad3f3SBenjamin Herrenschmidt u32 reject; 588bc5ad3f3SBenjamin Herrenschmidt bool resend; 589bc5ad3f3SBenjamin Herrenschmidt bool local; 590bc5ad3f3SBenjamin Herrenschmidt 591bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("h_ipi vcpu %d to server %lu mfrr %#lx\n", 592bc5ad3f3SBenjamin Herrenschmidt vcpu->vcpu_id, server, mfrr); 593bc5ad3f3SBenjamin Herrenschmidt 594bc5ad3f3SBenjamin Herrenschmidt icp = vcpu->arch.icp; 595bc5ad3f3SBenjamin Herrenschmidt local = icp->server_num == server; 596bc5ad3f3SBenjamin Herrenschmidt if (!local) { 597bc5ad3f3SBenjamin Herrenschmidt icp = kvmppc_xics_find_server(vcpu->kvm, server); 598bc5ad3f3SBenjamin Herrenschmidt if (!icp) 599bc5ad3f3SBenjamin Herrenschmidt return H_PARAMETER; 600bc5ad3f3SBenjamin Herrenschmidt } 601bc5ad3f3SBenjamin Herrenschmidt 602bc5ad3f3SBenjamin Herrenschmidt /* 603bc5ad3f3SBenjamin Herrenschmidt * ICP state: Set_MFRR 604bc5ad3f3SBenjamin Herrenschmidt * 605bc5ad3f3SBenjamin Herrenschmidt * If the CPPR is more favored than the new MFRR, then 606bc5ad3f3SBenjamin Herrenschmidt * nothing needs to be rejected as there can be no XISR to 607bc5ad3f3SBenjamin Herrenschmidt * reject. If the MFRR is being made less favored then 608bc5ad3f3SBenjamin Herrenschmidt * there might be a previously-rejected interrupt needing 609bc5ad3f3SBenjamin Herrenschmidt * to be resent. 610bc5ad3f3SBenjamin Herrenschmidt * 611bc5ad3f3SBenjamin Herrenschmidt * If the CPPR is less favored, then we might be replacing 612bc5ad3f3SBenjamin Herrenschmidt * an interrupt, and thus need to possibly reject it as in 613bc5ad3f3SBenjamin Herrenschmidt * 614bc5ad3f3SBenjamin Herrenschmidt * ICP state: Check_IPI 615bc5ad3f3SBenjamin Herrenschmidt */ 616bc5ad3f3SBenjamin Herrenschmidt do { 617bc5ad3f3SBenjamin Herrenschmidt old_state = new_state = ACCESS_ONCE(icp->state); 618bc5ad3f3SBenjamin Herrenschmidt 619bc5ad3f3SBenjamin Herrenschmidt /* Set_MFRR */ 620bc5ad3f3SBenjamin Herrenschmidt new_state.mfrr = mfrr; 621bc5ad3f3SBenjamin Herrenschmidt 622bc5ad3f3SBenjamin Herrenschmidt /* Check_IPI */ 623bc5ad3f3SBenjamin Herrenschmidt reject = 0; 624bc5ad3f3SBenjamin Herrenschmidt resend = false; 625bc5ad3f3SBenjamin Herrenschmidt if (mfrr < new_state.cppr) { 626bc5ad3f3SBenjamin Herrenschmidt /* Reject a pending interrupt if not an IPI */ 627bc5ad3f3SBenjamin Herrenschmidt if (mfrr <= new_state.pending_pri) 628bc5ad3f3SBenjamin Herrenschmidt reject = new_state.xisr; 629bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri = mfrr; 630bc5ad3f3SBenjamin Herrenschmidt new_state.xisr = XICS_IPI; 631bc5ad3f3SBenjamin Herrenschmidt } 632bc5ad3f3SBenjamin Herrenschmidt 633bc5ad3f3SBenjamin Herrenschmidt if (mfrr > old_state.mfrr && mfrr > new_state.cppr) { 634bc5ad3f3SBenjamin Herrenschmidt resend = new_state.need_resend; 635bc5ad3f3SBenjamin Herrenschmidt new_state.need_resend = 0; 636bc5ad3f3SBenjamin Herrenschmidt } 637bc5ad3f3SBenjamin Herrenschmidt } while (!icp_try_update(icp, old_state, new_state, local)); 638bc5ad3f3SBenjamin Herrenschmidt 639bc5ad3f3SBenjamin Herrenschmidt /* Handle reject */ 640bc5ad3f3SBenjamin Herrenschmidt if (reject && reject != XICS_IPI) 641bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, reject); 642bc5ad3f3SBenjamin Herrenschmidt 643bc5ad3f3SBenjamin Herrenschmidt /* Handle resend */ 644bc5ad3f3SBenjamin Herrenschmidt if (resend) 645bc5ad3f3SBenjamin Herrenschmidt icp_check_resend(xics, icp); 646bc5ad3f3SBenjamin Herrenschmidt 647bc5ad3f3SBenjamin Herrenschmidt return H_SUCCESS; 648bc5ad3f3SBenjamin Herrenschmidt } 649bc5ad3f3SBenjamin Herrenschmidt 650e7d26f28SBenjamin Herrenschmidt static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr) 651bc5ad3f3SBenjamin Herrenschmidt { 652bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state old_state, new_state; 653bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 654bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp = vcpu->arch.icp; 655bc5ad3f3SBenjamin Herrenschmidt u32 reject; 656bc5ad3f3SBenjamin Herrenschmidt 657bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("h_cppr vcpu %d cppr %#lx\n", vcpu->vcpu_id, cppr); 658bc5ad3f3SBenjamin Herrenschmidt 659bc5ad3f3SBenjamin Herrenschmidt /* 660bc5ad3f3SBenjamin Herrenschmidt * ICP State: Set_CPPR 661bc5ad3f3SBenjamin Herrenschmidt * 662bc5ad3f3SBenjamin Herrenschmidt * We can safely compare the new value with the current 663bc5ad3f3SBenjamin Herrenschmidt * value outside of the transaction as the CPPR is only 664bc5ad3f3SBenjamin Herrenschmidt * ever changed by the processor on itself 665bc5ad3f3SBenjamin Herrenschmidt */ 666bc5ad3f3SBenjamin Herrenschmidt if (cppr > icp->state.cppr) 667bc5ad3f3SBenjamin Herrenschmidt icp_down_cppr(xics, icp, cppr); 668bc5ad3f3SBenjamin Herrenschmidt else if (cppr == icp->state.cppr) 669bc5ad3f3SBenjamin Herrenschmidt return; 670bc5ad3f3SBenjamin Herrenschmidt 671bc5ad3f3SBenjamin Herrenschmidt /* 672bc5ad3f3SBenjamin Herrenschmidt * ICP State: Up_CPPR 673bc5ad3f3SBenjamin Herrenschmidt * 674bc5ad3f3SBenjamin Herrenschmidt * The processor is raising its priority, this can result 675bc5ad3f3SBenjamin Herrenschmidt * in a rejection of a pending interrupt: 676bc5ad3f3SBenjamin Herrenschmidt * 677bc5ad3f3SBenjamin Herrenschmidt * ICP State: Reject_Current 678bc5ad3f3SBenjamin Herrenschmidt * 679bc5ad3f3SBenjamin Herrenschmidt * We can remove EE from the current processor, the update 680bc5ad3f3SBenjamin Herrenschmidt * transaction will set it again if needed 681bc5ad3f3SBenjamin Herrenschmidt */ 682bc5ad3f3SBenjamin Herrenschmidt kvmppc_book3s_dequeue_irqprio(icp->vcpu, 683bc5ad3f3SBenjamin Herrenschmidt BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 684bc5ad3f3SBenjamin Herrenschmidt 685bc5ad3f3SBenjamin Herrenschmidt do { 686bc5ad3f3SBenjamin Herrenschmidt old_state = new_state = ACCESS_ONCE(icp->state); 687bc5ad3f3SBenjamin Herrenschmidt 688bc5ad3f3SBenjamin Herrenschmidt reject = 0; 689bc5ad3f3SBenjamin Herrenschmidt new_state.cppr = cppr; 690bc5ad3f3SBenjamin Herrenschmidt 691bc5ad3f3SBenjamin Herrenschmidt if (cppr <= new_state.pending_pri) { 692bc5ad3f3SBenjamin Herrenschmidt reject = new_state.xisr; 693bc5ad3f3SBenjamin Herrenschmidt new_state.xisr = 0; 694bc5ad3f3SBenjamin Herrenschmidt new_state.pending_pri = 0xff; 695bc5ad3f3SBenjamin Herrenschmidt } 696bc5ad3f3SBenjamin Herrenschmidt 697bc5ad3f3SBenjamin Herrenschmidt } while (!icp_try_update(icp, old_state, new_state, true)); 698bc5ad3f3SBenjamin Herrenschmidt 699bc5ad3f3SBenjamin Herrenschmidt /* 700bc5ad3f3SBenjamin Herrenschmidt * Check for rejects. They are handled by doing a new delivery 701bc5ad3f3SBenjamin Herrenschmidt * attempt (see comments in icp_deliver_irq). 702bc5ad3f3SBenjamin Herrenschmidt */ 703bc5ad3f3SBenjamin Herrenschmidt if (reject && reject != XICS_IPI) 704bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, reject); 705bc5ad3f3SBenjamin Herrenschmidt } 706bc5ad3f3SBenjamin Herrenschmidt 707e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) 708bc5ad3f3SBenjamin Herrenschmidt { 709bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 710bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp = vcpu->arch.icp; 711bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 712bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *state; 713bc5ad3f3SBenjamin Herrenschmidt u32 irq = xirr & 0x00ffffff; 714bc5ad3f3SBenjamin Herrenschmidt u16 src; 715bc5ad3f3SBenjamin Herrenschmidt 716bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("h_eoi vcpu %d eoi %#lx\n", vcpu->vcpu_id, xirr); 717bc5ad3f3SBenjamin Herrenschmidt 718bc5ad3f3SBenjamin Herrenschmidt /* 719bc5ad3f3SBenjamin Herrenschmidt * ICP State: EOI 720bc5ad3f3SBenjamin Herrenschmidt * 721bc5ad3f3SBenjamin Herrenschmidt * Note: If EOI is incorrectly used by SW to lower the CPPR 722bc5ad3f3SBenjamin Herrenschmidt * value (ie more favored), we do not check for rejection of 723bc5ad3f3SBenjamin Herrenschmidt * a pending interrupt, this is a SW error and PAPR sepcifies 724bc5ad3f3SBenjamin Herrenschmidt * that we don't have to deal with it. 725bc5ad3f3SBenjamin Herrenschmidt * 726bc5ad3f3SBenjamin Herrenschmidt * The sending of an EOI to the ICS is handled after the 727bc5ad3f3SBenjamin Herrenschmidt * CPPR update 728bc5ad3f3SBenjamin Herrenschmidt * 729bc5ad3f3SBenjamin Herrenschmidt * ICP State: Down_CPPR which we handle 730bc5ad3f3SBenjamin Herrenschmidt * in a separate function as it's shared with H_CPPR. 731bc5ad3f3SBenjamin Herrenschmidt */ 732bc5ad3f3SBenjamin Herrenschmidt icp_down_cppr(xics, icp, xirr >> 24); 733bc5ad3f3SBenjamin Herrenschmidt 734bc5ad3f3SBenjamin Herrenschmidt /* IPIs have no EOI */ 735bc5ad3f3SBenjamin Herrenschmidt if (irq == XICS_IPI) 736bc5ad3f3SBenjamin Herrenschmidt return H_SUCCESS; 737bc5ad3f3SBenjamin Herrenschmidt /* 738bc5ad3f3SBenjamin Herrenschmidt * EOI handling: If the interrupt is still asserted, we need to 739bc5ad3f3SBenjamin Herrenschmidt * resend it. We can take a lockless "peek" at the ICS state here. 740bc5ad3f3SBenjamin Herrenschmidt * 741bc5ad3f3SBenjamin Herrenschmidt * "Message" interrupts will never have "asserted" set 742bc5ad3f3SBenjamin Herrenschmidt */ 743bc5ad3f3SBenjamin Herrenschmidt ics = kvmppc_xics_find_ics(xics, irq, &src); 744bc5ad3f3SBenjamin Herrenschmidt if (!ics) { 745bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("h_eoi: IRQ 0x%06x not found !\n", irq); 746bc5ad3f3SBenjamin Herrenschmidt return H_PARAMETER; 747bc5ad3f3SBenjamin Herrenschmidt } 748bc5ad3f3SBenjamin Herrenschmidt state = &ics->irq_state[src]; 749bc5ad3f3SBenjamin Herrenschmidt 750bc5ad3f3SBenjamin Herrenschmidt /* Still asserted, resend it */ 751bc5ad3f3SBenjamin Herrenschmidt if (state->asserted) 752bc5ad3f3SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, irq); 753bc5ad3f3SBenjamin Herrenschmidt 754bc5ad3f3SBenjamin Herrenschmidt return H_SUCCESS; 755bc5ad3f3SBenjamin Herrenschmidt } 756bc5ad3f3SBenjamin Herrenschmidt 757e7d26f28SBenjamin Herrenschmidt static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall) 758e7d26f28SBenjamin Herrenschmidt { 759e7d26f28SBenjamin Herrenschmidt struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 760e7d26f28SBenjamin Herrenschmidt struct kvmppc_icp *icp = vcpu->arch.icp; 761e7d26f28SBenjamin Herrenschmidt 762e7d26f28SBenjamin Herrenschmidt XICS_DBG("XICS_RM: H_%x completing, act: %x state: %lx tgt: %p\n", 763e7d26f28SBenjamin Herrenschmidt hcall, icp->rm_action, icp->rm_dbgstate.raw, icp->rm_dbgtgt); 764e7d26f28SBenjamin Herrenschmidt 765e7d26f28SBenjamin Herrenschmidt if (icp->rm_action & XICS_RM_KICK_VCPU) 766e7d26f28SBenjamin Herrenschmidt kvmppc_fast_vcpu_kick(icp->rm_kick_target); 767e7d26f28SBenjamin Herrenschmidt if (icp->rm_action & XICS_RM_CHECK_RESEND) 768e7d26f28SBenjamin Herrenschmidt icp_check_resend(xics, icp); 769e7d26f28SBenjamin Herrenschmidt if (icp->rm_action & XICS_RM_REJECT) 770e7d26f28SBenjamin Herrenschmidt icp_deliver_irq(xics, icp, icp->rm_reject); 771e7d26f28SBenjamin Herrenschmidt 772e7d26f28SBenjamin Herrenschmidt icp->rm_action = 0; 773e7d26f28SBenjamin Herrenschmidt 774e7d26f28SBenjamin Herrenschmidt return H_SUCCESS; 775e7d26f28SBenjamin Herrenschmidt } 776e7d26f28SBenjamin Herrenschmidt 777bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) 778bc5ad3f3SBenjamin Herrenschmidt { 779e7d26f28SBenjamin Herrenschmidt struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 780bc5ad3f3SBenjamin Herrenschmidt unsigned long res; 781bc5ad3f3SBenjamin Herrenschmidt int rc = H_SUCCESS; 782bc5ad3f3SBenjamin Herrenschmidt 783bc5ad3f3SBenjamin Herrenschmidt /* Check if we have an ICP */ 784e7d26f28SBenjamin Herrenschmidt if (!xics || !vcpu->arch.icp) 785bc5ad3f3SBenjamin Herrenschmidt return H_HARDWARE; 786bc5ad3f3SBenjamin Herrenschmidt 787e7d26f28SBenjamin Herrenschmidt /* Check for real mode returning too hard */ 788e7d26f28SBenjamin Herrenschmidt if (xics->real_mode) 789e7d26f28SBenjamin Herrenschmidt return kvmppc_xics_rm_complete(vcpu, req); 790e7d26f28SBenjamin Herrenschmidt 791bc5ad3f3SBenjamin Herrenschmidt switch (req) { 792bc5ad3f3SBenjamin Herrenschmidt case H_XIRR: 793e7d26f28SBenjamin Herrenschmidt res = kvmppc_h_xirr(vcpu); 794bc5ad3f3SBenjamin Herrenschmidt kvmppc_set_gpr(vcpu, 4, res); 795bc5ad3f3SBenjamin Herrenschmidt break; 796bc5ad3f3SBenjamin Herrenschmidt case H_CPPR: 797e7d26f28SBenjamin Herrenschmidt kvmppc_h_cppr(vcpu, kvmppc_get_gpr(vcpu, 4)); 798bc5ad3f3SBenjamin Herrenschmidt break; 799bc5ad3f3SBenjamin Herrenschmidt case H_EOI: 800e7d26f28SBenjamin Herrenschmidt rc = kvmppc_h_eoi(vcpu, kvmppc_get_gpr(vcpu, 4)); 801bc5ad3f3SBenjamin Herrenschmidt break; 802bc5ad3f3SBenjamin Herrenschmidt case H_IPI: 803e7d26f28SBenjamin Herrenschmidt rc = kvmppc_h_ipi(vcpu, kvmppc_get_gpr(vcpu, 4), 804bc5ad3f3SBenjamin Herrenschmidt kvmppc_get_gpr(vcpu, 5)); 805bc5ad3f3SBenjamin Herrenschmidt break; 806bc5ad3f3SBenjamin Herrenschmidt } 807bc5ad3f3SBenjamin Herrenschmidt 808bc5ad3f3SBenjamin Herrenschmidt return rc; 809bc5ad3f3SBenjamin Herrenschmidt } 810bc5ad3f3SBenjamin Herrenschmidt 811bc5ad3f3SBenjamin Herrenschmidt 812bc5ad3f3SBenjamin Herrenschmidt /* -- Initialisation code etc. -- */ 813bc5ad3f3SBenjamin Herrenschmidt 814bc5ad3f3SBenjamin Herrenschmidt static int xics_debug_show(struct seq_file *m, void *private) 815bc5ad3f3SBenjamin Herrenschmidt { 816bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics = m->private; 817bc5ad3f3SBenjamin Herrenschmidt struct kvm *kvm = xics->kvm; 818bc5ad3f3SBenjamin Herrenschmidt struct kvm_vcpu *vcpu; 819bc5ad3f3SBenjamin Herrenschmidt int icsid, i; 820bc5ad3f3SBenjamin Herrenschmidt 821bc5ad3f3SBenjamin Herrenschmidt if (!kvm) 822bc5ad3f3SBenjamin Herrenschmidt return 0; 823bc5ad3f3SBenjamin Herrenschmidt 824bc5ad3f3SBenjamin Herrenschmidt seq_printf(m, "=========\nICP state\n=========\n"); 825bc5ad3f3SBenjamin Herrenschmidt 826bc5ad3f3SBenjamin Herrenschmidt kvm_for_each_vcpu(i, vcpu, kvm) { 827bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp = vcpu->arch.icp; 828bc5ad3f3SBenjamin Herrenschmidt union kvmppc_icp_state state; 829bc5ad3f3SBenjamin Herrenschmidt 830bc5ad3f3SBenjamin Herrenschmidt if (!icp) 831bc5ad3f3SBenjamin Herrenschmidt continue; 832bc5ad3f3SBenjamin Herrenschmidt 833bc5ad3f3SBenjamin Herrenschmidt state.raw = ACCESS_ONCE(icp->state.raw); 834bc5ad3f3SBenjamin Herrenschmidt seq_printf(m, "cpu server %#lx XIRR:%#x PPRI:%#x CPPR:%#x MFRR:%#x OUT:%d NR:%d\n", 835bc5ad3f3SBenjamin Herrenschmidt icp->server_num, state.xisr, 836bc5ad3f3SBenjamin Herrenschmidt state.pending_pri, state.cppr, state.mfrr, 837bc5ad3f3SBenjamin Herrenschmidt state.out_ee, state.need_resend); 838bc5ad3f3SBenjamin Herrenschmidt } 839bc5ad3f3SBenjamin Herrenschmidt 840bc5ad3f3SBenjamin Herrenschmidt for (icsid = 0; icsid <= KVMPPC_XICS_MAX_ICS_ID; icsid++) { 841bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics = xics->ics[icsid]; 842bc5ad3f3SBenjamin Herrenschmidt 843bc5ad3f3SBenjamin Herrenschmidt if (!ics) 844bc5ad3f3SBenjamin Herrenschmidt continue; 845bc5ad3f3SBenjamin Herrenschmidt 846bc5ad3f3SBenjamin Herrenschmidt seq_printf(m, "=========\nICS state for ICS 0x%x\n=========\n", 847bc5ad3f3SBenjamin Herrenschmidt icsid); 848bc5ad3f3SBenjamin Herrenschmidt 849bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&ics->lock); 850bc5ad3f3SBenjamin Herrenschmidt 851bc5ad3f3SBenjamin Herrenschmidt for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { 852bc5ad3f3SBenjamin Herrenschmidt struct ics_irq_state *irq = &ics->irq_state[i]; 853bc5ad3f3SBenjamin Herrenschmidt 854bc5ad3f3SBenjamin Herrenschmidt seq_printf(m, "irq 0x%06x: server %#x prio %#x save prio %#x asserted %d resend %d masked pending %d\n", 855bc5ad3f3SBenjamin Herrenschmidt irq->number, irq->server, irq->priority, 856bc5ad3f3SBenjamin Herrenschmidt irq->saved_priority, irq->asserted, 857bc5ad3f3SBenjamin Herrenschmidt irq->resend, irq->masked_pending); 858bc5ad3f3SBenjamin Herrenschmidt 859bc5ad3f3SBenjamin Herrenschmidt } 860bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&ics->lock); 861bc5ad3f3SBenjamin Herrenschmidt } 862bc5ad3f3SBenjamin Herrenschmidt return 0; 863bc5ad3f3SBenjamin Herrenschmidt } 864bc5ad3f3SBenjamin Herrenschmidt 865bc5ad3f3SBenjamin Herrenschmidt static int xics_debug_open(struct inode *inode, struct file *file) 866bc5ad3f3SBenjamin Herrenschmidt { 867bc5ad3f3SBenjamin Herrenschmidt return single_open(file, xics_debug_show, inode->i_private); 868bc5ad3f3SBenjamin Herrenschmidt } 869bc5ad3f3SBenjamin Herrenschmidt 870bc5ad3f3SBenjamin Herrenschmidt static const struct file_operations xics_debug_fops = { 871bc5ad3f3SBenjamin Herrenschmidt .open = xics_debug_open, 872bc5ad3f3SBenjamin Herrenschmidt .read = seq_read, 873bc5ad3f3SBenjamin Herrenschmidt .llseek = seq_lseek, 874bc5ad3f3SBenjamin Herrenschmidt .release = single_release, 875bc5ad3f3SBenjamin Herrenschmidt }; 876bc5ad3f3SBenjamin Herrenschmidt 877bc5ad3f3SBenjamin Herrenschmidt static void xics_debugfs_init(struct kvmppc_xics *xics) 878bc5ad3f3SBenjamin Herrenschmidt { 879bc5ad3f3SBenjamin Herrenschmidt char *name; 880bc5ad3f3SBenjamin Herrenschmidt 881bc5ad3f3SBenjamin Herrenschmidt name = kasprintf(GFP_KERNEL, "kvm-xics-%p", xics); 882bc5ad3f3SBenjamin Herrenschmidt if (!name) { 883bc5ad3f3SBenjamin Herrenschmidt pr_err("%s: no memory for name\n", __func__); 884bc5ad3f3SBenjamin Herrenschmidt return; 885bc5ad3f3SBenjamin Herrenschmidt } 886bc5ad3f3SBenjamin Herrenschmidt 887bc5ad3f3SBenjamin Herrenschmidt xics->dentry = debugfs_create_file(name, S_IRUGO, powerpc_debugfs_root, 888bc5ad3f3SBenjamin Herrenschmidt xics, &xics_debug_fops); 889bc5ad3f3SBenjamin Herrenschmidt 890bc5ad3f3SBenjamin Herrenschmidt pr_debug("%s: created %s\n", __func__, name); 891bc5ad3f3SBenjamin Herrenschmidt kfree(name); 892bc5ad3f3SBenjamin Herrenschmidt } 893bc5ad3f3SBenjamin Herrenschmidt 894bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *kvmppc_xics_create_ics(struct kvm *kvm, 895bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics, int irq) 896bc5ad3f3SBenjamin Herrenschmidt { 897bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_ics *ics; 898bc5ad3f3SBenjamin Herrenschmidt int i, icsid; 899bc5ad3f3SBenjamin Herrenschmidt 900bc5ad3f3SBenjamin Herrenschmidt icsid = irq >> KVMPPC_XICS_ICS_SHIFT; 901bc5ad3f3SBenjamin Herrenschmidt 902bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&kvm->lock); 903bc5ad3f3SBenjamin Herrenschmidt 904bc5ad3f3SBenjamin Herrenschmidt /* ICS already exists - somebody else got here first */ 905bc5ad3f3SBenjamin Herrenschmidt if (xics->ics[icsid]) 906bc5ad3f3SBenjamin Herrenschmidt goto out; 907bc5ad3f3SBenjamin Herrenschmidt 908bc5ad3f3SBenjamin Herrenschmidt /* Create the ICS */ 909bc5ad3f3SBenjamin Herrenschmidt ics = kzalloc(sizeof(struct kvmppc_ics), GFP_KERNEL); 910bc5ad3f3SBenjamin Herrenschmidt if (!ics) 911bc5ad3f3SBenjamin Herrenschmidt goto out; 912bc5ad3f3SBenjamin Herrenschmidt 913bc5ad3f3SBenjamin Herrenschmidt mutex_init(&ics->lock); 914bc5ad3f3SBenjamin Herrenschmidt ics->icsid = icsid; 915bc5ad3f3SBenjamin Herrenschmidt 916bc5ad3f3SBenjamin Herrenschmidt for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) { 917bc5ad3f3SBenjamin Herrenschmidt ics->irq_state[i].number = (icsid << KVMPPC_XICS_ICS_SHIFT) | i; 918bc5ad3f3SBenjamin Herrenschmidt ics->irq_state[i].priority = MASKED; 919bc5ad3f3SBenjamin Herrenschmidt ics->irq_state[i].saved_priority = MASKED; 920bc5ad3f3SBenjamin Herrenschmidt } 921bc5ad3f3SBenjamin Herrenschmidt smp_wmb(); 922bc5ad3f3SBenjamin Herrenschmidt xics->ics[icsid] = ics; 923bc5ad3f3SBenjamin Herrenschmidt 924bc5ad3f3SBenjamin Herrenschmidt if (icsid > xics->max_icsid) 925bc5ad3f3SBenjamin Herrenschmidt xics->max_icsid = icsid; 926bc5ad3f3SBenjamin Herrenschmidt 927bc5ad3f3SBenjamin Herrenschmidt out: 928bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&kvm->lock); 929bc5ad3f3SBenjamin Herrenschmidt return xics->ics[icsid]; 930bc5ad3f3SBenjamin Herrenschmidt } 931bc5ad3f3SBenjamin Herrenschmidt 932bc5ad3f3SBenjamin Herrenschmidt int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server_num) 933bc5ad3f3SBenjamin Herrenschmidt { 934bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_icp *icp; 935bc5ad3f3SBenjamin Herrenschmidt 936bc5ad3f3SBenjamin Herrenschmidt if (!vcpu->kvm->arch.xics) 937bc5ad3f3SBenjamin Herrenschmidt return -ENODEV; 938bc5ad3f3SBenjamin Herrenschmidt 939bc5ad3f3SBenjamin Herrenschmidt if (kvmppc_xics_find_server(vcpu->kvm, server_num)) 940bc5ad3f3SBenjamin Herrenschmidt return -EEXIST; 941bc5ad3f3SBenjamin Herrenschmidt 942bc5ad3f3SBenjamin Herrenschmidt icp = kzalloc(sizeof(struct kvmppc_icp), GFP_KERNEL); 943bc5ad3f3SBenjamin Herrenschmidt if (!icp) 944bc5ad3f3SBenjamin Herrenschmidt return -ENOMEM; 945bc5ad3f3SBenjamin Herrenschmidt 946bc5ad3f3SBenjamin Herrenschmidt icp->vcpu = vcpu; 947bc5ad3f3SBenjamin Herrenschmidt icp->server_num = server_num; 948bc5ad3f3SBenjamin Herrenschmidt icp->state.mfrr = MASKED; 949bc5ad3f3SBenjamin Herrenschmidt icp->state.pending_pri = MASKED; 950bc5ad3f3SBenjamin Herrenschmidt vcpu->arch.icp = icp; 951bc5ad3f3SBenjamin Herrenschmidt 952bc5ad3f3SBenjamin Herrenschmidt XICS_DBG("created server for vcpu %d\n", vcpu->vcpu_id); 953bc5ad3f3SBenjamin Herrenschmidt 954bc5ad3f3SBenjamin Herrenschmidt return 0; 955bc5ad3f3SBenjamin Herrenschmidt } 956bc5ad3f3SBenjamin Herrenschmidt 957*8b78645cSPaul Mackerras u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu) 958*8b78645cSPaul Mackerras { 959*8b78645cSPaul Mackerras struct kvmppc_icp *icp = vcpu->arch.icp; 960*8b78645cSPaul Mackerras union kvmppc_icp_state state; 961*8b78645cSPaul Mackerras 962*8b78645cSPaul Mackerras if (!icp) 963*8b78645cSPaul Mackerras return 0; 964*8b78645cSPaul Mackerras state = icp->state; 965*8b78645cSPaul Mackerras return ((u64)state.cppr << KVM_REG_PPC_ICP_CPPR_SHIFT) | 966*8b78645cSPaul Mackerras ((u64)state.xisr << KVM_REG_PPC_ICP_XISR_SHIFT) | 967*8b78645cSPaul Mackerras ((u64)state.mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT) | 968*8b78645cSPaul Mackerras ((u64)state.pending_pri << KVM_REG_PPC_ICP_PPRI_SHIFT); 969*8b78645cSPaul Mackerras } 970*8b78645cSPaul Mackerras 971*8b78645cSPaul Mackerras int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval) 972*8b78645cSPaul Mackerras { 973*8b78645cSPaul Mackerras struct kvmppc_icp *icp = vcpu->arch.icp; 974*8b78645cSPaul Mackerras struct kvmppc_xics *xics = vcpu->kvm->arch.xics; 975*8b78645cSPaul Mackerras union kvmppc_icp_state old_state, new_state; 976*8b78645cSPaul Mackerras struct kvmppc_ics *ics; 977*8b78645cSPaul Mackerras u8 cppr, mfrr, pending_pri; 978*8b78645cSPaul Mackerras u32 xisr; 979*8b78645cSPaul Mackerras u16 src; 980*8b78645cSPaul Mackerras bool resend; 981*8b78645cSPaul Mackerras 982*8b78645cSPaul Mackerras if (!icp || !xics) 983*8b78645cSPaul Mackerras return -ENOENT; 984*8b78645cSPaul Mackerras 985*8b78645cSPaul Mackerras cppr = icpval >> KVM_REG_PPC_ICP_CPPR_SHIFT; 986*8b78645cSPaul Mackerras xisr = (icpval >> KVM_REG_PPC_ICP_XISR_SHIFT) & 987*8b78645cSPaul Mackerras KVM_REG_PPC_ICP_XISR_MASK; 988*8b78645cSPaul Mackerras mfrr = icpval >> KVM_REG_PPC_ICP_MFRR_SHIFT; 989*8b78645cSPaul Mackerras pending_pri = icpval >> KVM_REG_PPC_ICP_PPRI_SHIFT; 990*8b78645cSPaul Mackerras 991*8b78645cSPaul Mackerras /* Require the new state to be internally consistent */ 992*8b78645cSPaul Mackerras if (xisr == 0) { 993*8b78645cSPaul Mackerras if (pending_pri != 0xff) 994*8b78645cSPaul Mackerras return -EINVAL; 995*8b78645cSPaul Mackerras } else if (xisr == XICS_IPI) { 996*8b78645cSPaul Mackerras if (pending_pri != mfrr || pending_pri >= cppr) 997*8b78645cSPaul Mackerras return -EINVAL; 998*8b78645cSPaul Mackerras } else { 999*8b78645cSPaul Mackerras if (pending_pri >= mfrr || pending_pri >= cppr) 1000*8b78645cSPaul Mackerras return -EINVAL; 1001*8b78645cSPaul Mackerras ics = kvmppc_xics_find_ics(xics, xisr, &src); 1002*8b78645cSPaul Mackerras if (!ics) 1003*8b78645cSPaul Mackerras return -EINVAL; 1004*8b78645cSPaul Mackerras } 1005*8b78645cSPaul Mackerras 1006*8b78645cSPaul Mackerras new_state.raw = 0; 1007*8b78645cSPaul Mackerras new_state.cppr = cppr; 1008*8b78645cSPaul Mackerras new_state.xisr = xisr; 1009*8b78645cSPaul Mackerras new_state.mfrr = mfrr; 1010*8b78645cSPaul Mackerras new_state.pending_pri = pending_pri; 1011*8b78645cSPaul Mackerras 1012*8b78645cSPaul Mackerras /* 1013*8b78645cSPaul Mackerras * Deassert the CPU interrupt request. 1014*8b78645cSPaul Mackerras * icp_try_update will reassert it if necessary. 1015*8b78645cSPaul Mackerras */ 1016*8b78645cSPaul Mackerras kvmppc_book3s_dequeue_irqprio(icp->vcpu, 1017*8b78645cSPaul Mackerras BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 1018*8b78645cSPaul Mackerras 1019*8b78645cSPaul Mackerras /* 1020*8b78645cSPaul Mackerras * Note that if we displace an interrupt from old_state.xisr, 1021*8b78645cSPaul Mackerras * we don't mark it as rejected. We expect userspace to set 1022*8b78645cSPaul Mackerras * the state of the interrupt sources to be consistent with 1023*8b78645cSPaul Mackerras * the ICP states (either before or afterwards, which doesn't 1024*8b78645cSPaul Mackerras * matter). We do handle resends due to CPPR becoming less 1025*8b78645cSPaul Mackerras * favoured because that is necessary to end up with a 1026*8b78645cSPaul Mackerras * consistent state in the situation where userspace restores 1027*8b78645cSPaul Mackerras * the ICS states before the ICP states. 1028*8b78645cSPaul Mackerras */ 1029*8b78645cSPaul Mackerras do { 1030*8b78645cSPaul Mackerras old_state = ACCESS_ONCE(icp->state); 1031*8b78645cSPaul Mackerras 1032*8b78645cSPaul Mackerras if (new_state.mfrr <= old_state.mfrr) { 1033*8b78645cSPaul Mackerras resend = false; 1034*8b78645cSPaul Mackerras new_state.need_resend = old_state.need_resend; 1035*8b78645cSPaul Mackerras } else { 1036*8b78645cSPaul Mackerras resend = old_state.need_resend; 1037*8b78645cSPaul Mackerras new_state.need_resend = 0; 1038*8b78645cSPaul Mackerras } 1039*8b78645cSPaul Mackerras } while (!icp_try_update(icp, old_state, new_state, false)); 1040*8b78645cSPaul Mackerras 1041*8b78645cSPaul Mackerras if (resend) 1042*8b78645cSPaul Mackerras icp_check_resend(xics, icp); 1043*8b78645cSPaul Mackerras 1044*8b78645cSPaul Mackerras return 0; 1045*8b78645cSPaul Mackerras } 1046*8b78645cSPaul Mackerras 1047bc5ad3f3SBenjamin Herrenschmidt /* -- ioctls -- */ 1048bc5ad3f3SBenjamin Herrenschmidt 1049bc5ad3f3SBenjamin Herrenschmidt int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args) 1050bc5ad3f3SBenjamin Herrenschmidt { 1051bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics; 1052bc5ad3f3SBenjamin Herrenschmidt int r; 1053bc5ad3f3SBenjamin Herrenschmidt 1054bc5ad3f3SBenjamin Herrenschmidt /* locking against multiple callers? */ 1055bc5ad3f3SBenjamin Herrenschmidt 1056bc5ad3f3SBenjamin Herrenschmidt xics = kvm->arch.xics; 1057bc5ad3f3SBenjamin Herrenschmidt if (!xics) 1058bc5ad3f3SBenjamin Herrenschmidt return -ENODEV; 1059bc5ad3f3SBenjamin Herrenschmidt 1060bc5ad3f3SBenjamin Herrenschmidt switch (args->level) { 1061bc5ad3f3SBenjamin Herrenschmidt case KVM_INTERRUPT_SET: 1062bc5ad3f3SBenjamin Herrenschmidt case KVM_INTERRUPT_SET_LEVEL: 1063bc5ad3f3SBenjamin Herrenschmidt case KVM_INTERRUPT_UNSET: 1064bc5ad3f3SBenjamin Herrenschmidt r = ics_deliver_irq(xics, args->irq, args->level); 1065bc5ad3f3SBenjamin Herrenschmidt break; 1066bc5ad3f3SBenjamin Herrenschmidt default: 1067bc5ad3f3SBenjamin Herrenschmidt r = -EINVAL; 1068bc5ad3f3SBenjamin Herrenschmidt } 1069bc5ad3f3SBenjamin Herrenschmidt 1070bc5ad3f3SBenjamin Herrenschmidt return r; 1071bc5ad3f3SBenjamin Herrenschmidt } 1072bc5ad3f3SBenjamin Herrenschmidt 1073bc5ad3f3SBenjamin Herrenschmidt void kvmppc_xics_free(struct kvmppc_xics *xics) 1074bc5ad3f3SBenjamin Herrenschmidt { 1075bc5ad3f3SBenjamin Herrenschmidt int i; 1076bc5ad3f3SBenjamin Herrenschmidt struct kvm *kvm = xics->kvm; 1077bc5ad3f3SBenjamin Herrenschmidt 1078bc5ad3f3SBenjamin Herrenschmidt debugfs_remove(xics->dentry); 1079bc5ad3f3SBenjamin Herrenschmidt 1080bc5ad3f3SBenjamin Herrenschmidt if (kvm) 1081bc5ad3f3SBenjamin Herrenschmidt kvm->arch.xics = NULL; 1082bc5ad3f3SBenjamin Herrenschmidt 1083bc5ad3f3SBenjamin Herrenschmidt for (i = 0; i <= xics->max_icsid; i++) 1084bc5ad3f3SBenjamin Herrenschmidt kfree(xics->ics[i]); 1085bc5ad3f3SBenjamin Herrenschmidt kfree(xics); 1086bc5ad3f3SBenjamin Herrenschmidt } 1087bc5ad3f3SBenjamin Herrenschmidt 1088bc5ad3f3SBenjamin Herrenschmidt int kvm_xics_create(struct kvm *kvm, u32 type) 1089bc5ad3f3SBenjamin Herrenschmidt { 1090bc5ad3f3SBenjamin Herrenschmidt struct kvmppc_xics *xics; 1091bc5ad3f3SBenjamin Herrenschmidt int ret = 0; 1092bc5ad3f3SBenjamin Herrenschmidt 1093bc5ad3f3SBenjamin Herrenschmidt xics = kzalloc(sizeof(*xics), GFP_KERNEL); 1094bc5ad3f3SBenjamin Herrenschmidt if (!xics) 1095bc5ad3f3SBenjamin Herrenschmidt return -ENOMEM; 1096bc5ad3f3SBenjamin Herrenschmidt 1097bc5ad3f3SBenjamin Herrenschmidt xics->kvm = kvm; 1098bc5ad3f3SBenjamin Herrenschmidt 1099bc5ad3f3SBenjamin Herrenschmidt /* Already there ? */ 1100bc5ad3f3SBenjamin Herrenschmidt mutex_lock(&kvm->lock); 1101bc5ad3f3SBenjamin Herrenschmidt if (kvm->arch.xics) 1102bc5ad3f3SBenjamin Herrenschmidt ret = -EEXIST; 1103bc5ad3f3SBenjamin Herrenschmidt else 1104bc5ad3f3SBenjamin Herrenschmidt kvm->arch.xics = xics; 1105bc5ad3f3SBenjamin Herrenschmidt mutex_unlock(&kvm->lock); 1106bc5ad3f3SBenjamin Herrenschmidt 1107bc5ad3f3SBenjamin Herrenschmidt if (ret) 1108bc5ad3f3SBenjamin Herrenschmidt return ret; 1109bc5ad3f3SBenjamin Herrenschmidt 1110bc5ad3f3SBenjamin Herrenschmidt xics_debugfs_init(xics); 1111bc5ad3f3SBenjamin Herrenschmidt 1112e7d26f28SBenjamin Herrenschmidt #ifdef CONFIG_KVM_BOOK3S_64_HV 1113e7d26f28SBenjamin Herrenschmidt if (cpu_has_feature(CPU_FTR_ARCH_206)) { 1114e7d26f28SBenjamin Herrenschmidt /* Enable real mode support */ 1115e7d26f28SBenjamin Herrenschmidt xics->real_mode = ENABLE_REALMODE; 1116e7d26f28SBenjamin Herrenschmidt xics->real_mode_dbg = DEBUG_REALMODE; 1117e7d26f28SBenjamin Herrenschmidt } 1118e7d26f28SBenjamin Herrenschmidt #endif /* CONFIG_KVM_BOOK3S_64_HV */ 1119e7d26f28SBenjamin Herrenschmidt 1120bc5ad3f3SBenjamin Herrenschmidt return 0; 1121bc5ad3f3SBenjamin Herrenschmidt } 1122bc5ad3f3SBenjamin Herrenschmidt 1123bc5ad3f3SBenjamin Herrenschmidt void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) 1124bc5ad3f3SBenjamin Herrenschmidt { 1125bc5ad3f3SBenjamin Herrenschmidt if (!vcpu->arch.icp) 1126bc5ad3f3SBenjamin Herrenschmidt return; 1127bc5ad3f3SBenjamin Herrenschmidt kfree(vcpu->arch.icp); 1128bc5ad3f3SBenjamin Herrenschmidt vcpu->arch.icp = NULL; 1129bc5ad3f3SBenjamin Herrenschmidt vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT; 1130bc5ad3f3SBenjamin Herrenschmidt } 1131