linux/arch/powerpc/kvm/book3s_xics.h
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Michael Ellerman, IBM Corporation.
   3 * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License, version 2, as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#ifndef _KVM_PPC_BOOK3S_XICS_H
  11#define _KVM_PPC_BOOK3S_XICS_H
  12
  13/*
  14 * We use a two-level tree to store interrupt source information.
  15 * There are up to 1024 ICS nodes, each of which can represent
  16 * 1024 sources.
  17 */
  18#define KVMPPC_XICS_MAX_ICS_ID  1023
  19#define KVMPPC_XICS_ICS_SHIFT   10
  20#define KVMPPC_XICS_IRQ_PER_ICS (1 << KVMPPC_XICS_ICS_SHIFT)
  21#define KVMPPC_XICS_SRC_MASK    (KVMPPC_XICS_IRQ_PER_ICS - 1)
  22
  23/*
  24 * Interrupt source numbers below this are reserved, for example
  25 * 0 is "no interrupt", and 2 is used for IPIs.
  26 */
  27#define KVMPPC_XICS_FIRST_IRQ   16
  28#define KVMPPC_XICS_NR_IRQS     ((KVMPPC_XICS_MAX_ICS_ID + 1) * \
  29                                 KVMPPC_XICS_IRQ_PER_ICS)
  30
  31/* Priority value to use for disabling an interrupt */
  32#define MASKED  0xff
  33
  34/* State for one irq source */
  35struct ics_irq_state {
  36        u32 number;
  37        u32 server;
  38        u8  priority;
  39        u8  saved_priority;
  40        u8  resend;
  41        u8  masked_pending;
  42        u8  asserted; /* Only for LSI */
  43        u8  exists;
  44};
  45
  46/* Atomic ICP state, updated with a single compare & swap */
  47union kvmppc_icp_state {
  48        unsigned long raw;
  49        struct {
  50                u8 out_ee:1;
  51                u8 need_resend:1;
  52                u8 cppr;
  53                u8 mfrr;
  54                u8 pending_pri;
  55                u32 xisr;
  56        };
  57};
  58
  59/* One bit per ICS */
  60#define ICP_RESEND_MAP_SIZE     (KVMPPC_XICS_MAX_ICS_ID / BITS_PER_LONG + 1)
  61
  62struct kvmppc_icp {
  63        struct kvm_vcpu *vcpu;
  64        unsigned long server_num;
  65        union kvmppc_icp_state state;
  66        unsigned long resend_map[ICP_RESEND_MAP_SIZE];
  67
  68        /* Real mode might find something too hard, here's the action
  69         * it might request from virtual mode
  70         */
  71#define XICS_RM_KICK_VCPU       0x1
  72#define XICS_RM_CHECK_RESEND    0x2
  73#define XICS_RM_REJECT          0x4
  74#define XICS_RM_NOTIFY_EOI      0x8
  75        u32 rm_action;
  76        struct kvm_vcpu *rm_kick_target;
  77        struct kvmppc_icp *rm_resend_icp;
  78        u32  rm_reject;
  79        u32  rm_eoied_irq;
  80
  81        /* Counters for each reason we exited real mode */
  82        unsigned long n_rm_kick_vcpu;
  83        unsigned long n_rm_check_resend;
  84        unsigned long n_rm_reject;
  85        unsigned long n_rm_notify_eoi;
  86        /* Counters for handling ICP processing in real mode */
  87        unsigned long n_check_resend;
  88        unsigned long n_reject;
  89
  90        /* Debug stuff for real mode */
  91        union kvmppc_icp_state rm_dbgstate;
  92        struct kvm_vcpu *rm_dbgtgt;
  93};
  94
  95struct kvmppc_ics {
  96        arch_spinlock_t lock;
  97        u16 icsid;
  98        struct ics_irq_state irq_state[KVMPPC_XICS_IRQ_PER_ICS];
  99};
 100
 101struct kvmppc_xics {
 102        struct kvm *kvm;
 103        struct kvm_device *dev;
 104        struct dentry *dentry;
 105        u32 max_icsid;
 106        bool real_mode;
 107        bool real_mode_dbg;
 108        u32 err_noics;
 109        u32 err_noicp;
 110        struct kvmppc_ics *ics[KVMPPC_XICS_MAX_ICS_ID + 1];
 111};
 112
 113static inline struct kvmppc_icp *kvmppc_xics_find_server(struct kvm *kvm,
 114                                                         u32 nr)
 115{
 116        struct kvm_vcpu *vcpu = NULL;
 117        int i;
 118
 119        kvm_for_each_vcpu(i, vcpu, kvm) {
 120                if (vcpu->arch.icp && nr == vcpu->arch.icp->server_num)
 121                        return vcpu->arch.icp;
 122        }
 123        return NULL;
 124}
 125
 126static inline struct kvmppc_ics *kvmppc_xics_find_ics(struct kvmppc_xics *xics,
 127                                                      u32 irq, u16 *source)
 128{
 129        u32 icsid = irq >> KVMPPC_XICS_ICS_SHIFT;
 130        u16 src = irq & KVMPPC_XICS_SRC_MASK;
 131        struct kvmppc_ics *ics;
 132
 133        if (source)
 134                *source = src;
 135        if (icsid > KVMPPC_XICS_MAX_ICS_ID)
 136                return NULL;
 137        ics = xics->ics[icsid];
 138        if (!ics)
 139                return NULL;
 140        return ics;
 141}
 142
 143
 144#endif /* _KVM_PPC_BOOK3S_XICS_H */
 145