diff options
| author | Paul Mackerras <paulus@samba.org> | 2013-04-26 20:28:37 -0400 |
|---|---|---|
| committer | Alexander Graf <agraf@suse.de> | 2013-05-02 09:28:36 -0400 |
| commit | 5975a2e0950291a6bfe9fd5880e7952ff87764be (patch) | |
| tree | a27a2f6645a74ad756ac4a3eba21e1086beab25d | |
| parent | d133b40f2cdd527af01090ffd6a041485d1a29b4 (diff) | |
KVM: PPC: Book3S: Add API for in-kernel XICS emulation
This adds the API for userspace to instantiate an XICS device in a VM
and connect VCPUs to it. The API consists of a new device type for
the KVM_CREATE_DEVICE ioctl, a new capability KVM_CAP_IRQ_XICS, which
functions similarly to KVM_CAP_IRQ_MPIC, and the KVM_IRQ_LINE ioctl,
which is used to assert and deassert interrupt inputs of the XICS.
The XICS device has one attribute group, KVM_DEV_XICS_GRP_SOURCES.
Each attribute within this group corresponds to the state of one
interrupt source. The attribute number is the same as the interrupt
source number.
This does not support irq routing or irqfd yet.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
| -rw-r--r-- | Documentation/virtual/kvm/api.txt | 8 | ||||
| -rw-r--r-- | Documentation/virtual/kvm/devices/xics.txt | 66 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/uapi/asm/kvm.h | 12 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_xics.c | 190 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_xics.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/kvm/irq.h | 3 | ||||
| -rw-r--r-- | arch/powerpc/kvm/powerpc.c | 22 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 1 | ||||
| -rw-r--r-- | include/uapi/linux/kvm.h | 2 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 5 |
11 files changed, 287 insertions, 25 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index c09d1832e935..03492f95ed39 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
| @@ -2772,3 +2772,11 @@ Parameters: args[0] is the MPIC device fd | |||
| 2772 | args[1] is the MPIC CPU number for this vcpu | 2772 | args[1] is the MPIC CPU number for this vcpu |
| 2773 | 2773 | ||
| 2774 | This capability connects the vcpu to an in-kernel MPIC device. | 2774 | This capability connects the vcpu to an in-kernel MPIC device. |
| 2775 | |||
| 2776 | 6.7 KVM_CAP_IRQ_XICS | ||
| 2777 | |||
| 2778 | Architectures: ppc | ||
| 2779 | Parameters: args[0] is the XICS device fd | ||
| 2780 | args[1] is the XICS CPU number (server ID) for this vcpu | ||
| 2781 | |||
| 2782 | This capability connects the vcpu to an in-kernel XICS device. | ||
diff --git a/Documentation/virtual/kvm/devices/xics.txt b/Documentation/virtual/kvm/devices/xics.txt new file mode 100644 index 000000000000..42864935ac5d --- /dev/null +++ b/Documentation/virtual/kvm/devices/xics.txt | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | XICS interrupt controller | ||
| 2 | |||
| 3 | Device type supported: KVM_DEV_TYPE_XICS | ||
| 4 | |||
| 5 | Groups: | ||
| 6 | KVM_DEV_XICS_SOURCES | ||
| 7 | Attributes: One per interrupt source, indexed by the source number. | ||
| 8 | |||
| 9 | This device emulates the XICS (eXternal Interrupt Controller | ||
| 10 | Specification) defined in PAPR. The XICS has a set of interrupt | ||
| 11 | sources, each identified by a 20-bit source number, and a set of | ||
| 12 | Interrupt Control Presentation (ICP) entities, also called "servers", | ||
| 13 | each associated with a virtual CPU. | ||
| 14 | |||
| 15 | The ICP entities are created by enabling the KVM_CAP_IRQ_ARCH | ||
| 16 | capability for each vcpu, specifying KVM_CAP_IRQ_XICS in args[0] and | ||
| 17 | the interrupt server number (i.e. the vcpu number from the XICS's | ||
| 18 | point of view) in args[1] of the kvm_enable_cap struct. Each ICP has | ||
| 19 | 64 bits of state which can be read and written using the | ||
| 20 | KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls on the vcpu. The 64 bit | ||
| 21 | state word has the following bitfields, starting at the | ||
| 22 | least-significant end of the word: | ||
| 23 | |||
| 24 | * Unused, 16 bits | ||
| 25 | |||
| 26 | * Pending interrupt priority, 8 bits | ||
| 27 | Zero is the highest priority, 255 means no interrupt is pending. | ||
| 28 | |||
| 29 | * Pending IPI (inter-processor interrupt) priority, 8 bits | ||
| 30 | Zero is the highest priority, 255 means no IPI is pending. | ||
| 31 | |||
| 32 | * Pending interrupt source number, 24 bits | ||
| 33 | Zero means no interrupt pending, 2 means an IPI is pending | ||
| 34 | |||
| 35 | * Current processor priority, 8 bits | ||
| 36 | Zero is the highest priority, meaning no interrupts can be | ||
| 37 | delivered, and 255 is the lowest priority. | ||
| 38 | |||
| 39 | Each source has 64 bits of state that can be read and written using | ||
| 40 | the KVM_GET_DEVICE_ATTR and KVM_SET_DEVICE_ATTR ioctls, specifying the | ||
| 41 | KVM_DEV_XICS_SOURCES attribute group, with the attribute number being | ||
| 42 | the interrupt source number. The 64 bit state word has the following | ||
| 43 | bitfields, starting from the least-significant end of the word: | ||
| 44 | |||
| 45 | * Destination (server number), 32 bits | ||
| 46 | This specifies where the interrupt should be sent, and is the | ||
| 47 | interrupt server number specified for the destination vcpu. | ||
| 48 | |||
| 49 | * Priority, 8 bits | ||
| 50 | This is the priority specified for this interrupt source, where 0 is | ||
| 51 | the highest priority and 255 is the lowest. An interrupt with a | ||
| 52 | priority of 255 will never be delivered. | ||
| 53 | |||
| 54 | * Level sensitive flag, 1 bit | ||
| 55 | This bit is 1 for a level-sensitive interrupt source, or 0 for | ||
| 56 | edge-sensitive (or MSI). | ||
| 57 | |||
| 58 | * Masked flag, 1 bit | ||
| 59 | This bit is set to 1 if the interrupt is masked (cannot be delivered | ||
| 60 | regardless of its priority), for example by the ibm,int-off RTAS | ||
| 61 | call, or 0 if it is not masked. | ||
| 62 | |||
| 63 | * Pending flag, 1 bit | ||
| 64 | This bit is 1 if the source has a pending interrupt, otherwise 0. | ||
| 65 | |||
| 66 | Only one XICS instance may be created per VM. | ||
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index d7339df19259..a5287fe03d77 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
| @@ -315,6 +315,8 @@ extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args); | |||
| 315 | extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd); | 315 | extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd); |
| 316 | extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu); | 316 | extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu); |
| 317 | extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval); | 317 | extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval); |
| 318 | extern int kvmppc_xics_connect_vcpu(struct kvm_device *dev, | ||
| 319 | struct kvm_vcpu *vcpu, u32 cpu); | ||
| 318 | #else | 320 | #else |
| 319 | static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu) | 321 | static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu) |
| 320 | { return 0; } | 322 | { return 0; } |
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 427b9aca2a0f..0fb1a6e9ff90 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h | |||
| @@ -499,4 +499,16 @@ struct kvm_get_htab_header { | |||
| 499 | #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) | 499 | #define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a) |
| 500 | #define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b) | 500 | #define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b) |
| 501 | 501 | ||
| 502 | /* PPC64 eXternal Interrupt Controller Specification */ | ||
| 503 | #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */ | ||
| 504 | |||
| 505 | /* Layout of 64-bit source attribute values */ | ||
| 506 | #define KVM_XICS_DESTINATION_SHIFT 0 | ||
| 507 | #define KVM_XICS_DESTINATION_MASK 0xffffffffULL | ||
| 508 | #define KVM_XICS_PRIORITY_SHIFT 32 | ||
| 509 | #define KVM_XICS_PRIORITY_MASK 0xff | ||
| 510 | #define KVM_XICS_LEVEL_SENSITIVE (1ULL << 40) | ||
| 511 | #define KVM_XICS_MASKED (1ULL << 41) | ||
| 512 | #define KVM_XICS_PENDING (1ULL << 42) | ||
| 513 | |||
| 502 | #endif /* __LINUX_KVM_POWERPC_H */ | 514 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index ee841ed8a690..f7a103756618 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/kvm_host.h> | 11 | #include <linux/kvm_host.h> |
| 12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| 13 | #include <linux/gfp.h> | 13 | #include <linux/gfp.h> |
| 14 | #include <linux/anon_inodes.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
| 16 | #include <asm/kvm_book3s.h> | 17 | #include <asm/kvm_book3s.h> |
| @@ -55,8 +56,6 @@ | |||
| 55 | * | 56 | * |
| 56 | * - Make ICS lockless as well, or at least a per-interrupt lock or hashed | 57 | * - Make ICS lockless as well, or at least a per-interrupt lock or hashed |
| 57 | * locks array to improve scalability | 58 | * locks array to improve scalability |
| 58 | * | ||
| 59 | * - ioctl's to save/restore the entire state for snapshot & migration | ||
| 60 | */ | 59 | */ |
| 61 | 60 | ||
| 62 | /* -- ICS routines -- */ | 61 | /* -- ICS routines -- */ |
| @@ -64,7 +63,8 @@ | |||
| 64 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, | 63 | static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, |
| 65 | u32 new_irq); | 64 | u32 new_irq); |
| 66 | 65 | ||
| 67 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) | 66 | static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level, |
| 67 | bool report_status) | ||
| 68 | { | 68 | { |
| 69 | struct ics_irq_state *state; | 69 | struct ics_irq_state *state; |
| 70 | struct kvmppc_ics *ics; | 70 | struct kvmppc_ics *ics; |
| @@ -81,6 +81,9 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) | |||
| 81 | if (!state->exists) | 81 | if (!state->exists) |
| 82 | return -EINVAL; | 82 | return -EINVAL; |
| 83 | 83 | ||
| 84 | if (report_status) | ||
| 85 | return state->asserted; | ||
| 86 | |||
| 84 | /* | 87 | /* |
| 85 | * We set state->asserted locklessly. This should be fine as | 88 | * We set state->asserted locklessly. This should be fine as |
| 86 | * we are the only setter, thus concurrent access is undefined | 89 | * we are the only setter, thus concurrent access is undefined |
| @@ -96,7 +99,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level) | |||
| 96 | /* Attempt delivery */ | 99 | /* Attempt delivery */ |
| 97 | icp_deliver_irq(xics, NULL, irq); | 100 | icp_deliver_irq(xics, NULL, irq); |
