cregit-Linux how code gets into the kernel

Release 4.14 arch/powerpc/kvm/book3s_xics.h

Directory: arch/powerpc/kvm
/*
 * Copyright 2012 Michael Ellerman, IBM Corporation.
 * Copyright 2012 Benjamin Herrenschmidt, IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 */

#ifndef _KVM_PPC_BOOK3S_XICS_H

#define _KVM_PPC_BOOK3S_XICS_H

#ifdef CONFIG_KVM_XICS
/*
 * We use a two-level tree to store interrupt source information.
 * There are up to 1024 ICS nodes, each of which can represent
 * 1024 sources.
 */

#define KVMPPC_XICS_MAX_ICS_ID	1023

#define KVMPPC_XICS_ICS_SHIFT	10

#define KVMPPC_XICS_IRQ_PER_ICS	(1 << KVMPPC_XICS_ICS_SHIFT)

#define KVMPPC_XICS_SRC_MASK	(KVMPPC_XICS_IRQ_PER_ICS - 1)

/*
 * Interrupt source numbers below this are reserved, for example
 * 0 is "no interrupt", and 2 is used for IPIs.
 */

#define KVMPPC_XICS_FIRST_IRQ	16

#define KVMPPC_XICS_NR_IRQS	((KVMPPC_XICS_MAX_ICS_ID + 1) * \
                                 KVMPPC_XICS_IRQ_PER_ICS)

/* Priority value to use for disabling an interrupt */

#define MASKED	0xff


#define PQ_PRESENTED	1

#define PQ_QUEUED	2

/* State for one irq source */

struct ics_irq_state {
	
u32 number;
	
u32 server;
	
u32 pq_state;
	
u8  priority;
	
u8  saved_priority;
	
u8  resend;
	
u8  masked_pending;
	
u8  lsi;		/* level-sensitive interrupt */
	
u8  exists;
	
int intr_cpu;
	
u32 host_irq;
};

/* Atomic ICP state, updated with a single compare & swap */

union kvmppc_icp_state {
	
unsigned long raw;
	struct {
		
u8 out_ee:1;
		
u8 need_resend:1;
		
u8 cppr;
		
u8 mfrr;
		
u8 pending_pri;
		
u32 xisr;
	};
};

/* One bit per ICS */

#define ICP_RESEND_MAP_SIZE	(KVMPPC_XICS_MAX_ICS_ID / BITS_PER_LONG + 1)


struct kvmppc_icp {
	
struct kvm_vcpu *vcpu;
	
unsigned long server_num;
	
union kvmppc_icp_state state;
	
unsigned long resend_map[ICP_RESEND_MAP_SIZE];

	/* Real mode might find something too hard, here's the action
         * it might request from virtual mode
         */

#define XICS_RM_KICK_VCPU	0x1

#define XICS_RM_CHECK_RESEND	0x2

#define XICS_RM_NOTIFY_EOI	0x8
	
u32 rm_action;
	
struct kvm_vcpu *rm_kick_target;
	
struct kvmppc_icp *rm_resend_icp;
	
u32  rm_reject;
	
u32  rm_eoied_irq;

	/* Counters for each reason we exited real mode */
	
unsigned long n_rm_kick_vcpu;
	
unsigned long n_rm_check_resend;
	
unsigned long n_rm_notify_eoi;
	/* Counters for handling ICP processing in real mode */
	
unsigned long n_check_resend;
	
unsigned long n_reject;

	/* Debug stuff for real mode */
	
union kvmppc_icp_state rm_dbgstate;
	
struct kvm_vcpu *rm_dbgtgt;
};


struct kvmppc_ics {
	
arch_spinlock_t lock;
	
u16 icsid;
	
struct ics_irq_state irq_state[KVMPPC_XICS_IRQ_PER_ICS];
};


struct kvmppc_xics {
	
struct kvm *kvm;
	
struct kvm_device *dev;
	
struct dentry *dentry;
	
u32 max_icsid;
	
bool real_mode;
	
bool real_mode_dbg;
	
u32 err_noics;
	
u32 err_noicp;
	
struct kvmppc_ics *ics[KVMPPC_XICS_MAX_ICS_ID + 1];
};


static inline struct kvmppc_icp *kvmppc_xics_find_server(struct kvm *kvm, u32 nr) { struct kvm_vcpu *vcpu = NULL; int i; kvm_for_each_vcpu(i, vcpu, kvm) { if (vcpu->arch.icp && nr == vcpu->arch.icp->server_num) return vcpu->arch.icp; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Benjamin Herrenschmidt65100.00%1100.00%
Total65100.00%1100.00%


static inline struct kvmppc_ics *kvmppc_xics_find_ics(struct kvmppc_xics *xics, u32 irq, u16 *source) { u32 icsid = irq >> KVMPPC_XICS_ICS_SHIFT; u16 src = irq & KVMPPC_XICS_SRC_MASK; struct kvmppc_ics *ics; if (source) *source = src; if (icsid > KVMPPC_XICS_MAX_ICS_ID) return NULL; ics = xics->ics[icsid]; if (!ics) return NULL; return ics; }

Contributors

PersonTokensPropCommitsCommitProp
Benjamin Herrenschmidt78100.00%1100.00%
Total78100.00%1100.00%

extern unsigned long xics_rm_h_xirr(struct kvm_vcpu *vcpu); extern int xics_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, unsigned long mfrr); extern int xics_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr); extern int xics_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr); #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */

Overall Contributors

PersonTokensPropCommitsCommitProp
Benjamin Herrenschmidt42186.27%325.00%
Suresh E. Warrier346.97%433.33%
Paul Mackerras224.51%433.33%
Li Zhong112.25%18.33%
Total488100.00%12100.00%
Directory: arch/powerpc/kvm
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.