Skip to content

Commit 6520ca6

Browse files
legoaterpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Add a mapping for the source ESB pages
Each source is associated with an Event State Buffer (ESB) with a even/odd pair of pages which provides commands to manage the source: to trigger, to EOI, to turn off the source for instance. The custom VM fault handler will deduce the guest IRQ number from the offset of the fault, and the ESB page of the associated XIVE interrupt will be inserted into the VMA using the internal structure caching information on the interrupts. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
1 parent 39e9af3 commit 6520ca6

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

Documentation/virtual/kvm/devices/xive.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
3636
third (operating system) and the fourth (user level) are exposed the
3737
guest.
3838

39+
2. Event State Buffer (ESB)
40+
41+
Each source is associated with an Event State Buffer (ESB) with
42+
either a pair of even/odd pair of pages which provides commands to
43+
manage the source: to trigger, to EOI, to turn off the source for
44+
instance.
45+
3946
* Groups:
4047

4148
1. KVM_DEV_XIVE_GRP_CTRL

arch/powerpc/include/uapi/asm/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,5 +721,6 @@ struct kvm_ppc_xive_eq {
721721
#define KVM_XIVE_EQ_ALWAYS_NOTIFY 0x00000001
722722

723723
#define KVM_XIVE_TIMA_PAGE_OFFSET 0
724+
#define KVM_XIVE_ESB_PAGE_OFFSET 4
724725

725726
#endif /* __LINUX_KVM_POWERPC_H */

arch/powerpc/kvm/book3s_xive_native.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,59 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
165165
return rc;
166166
}
167167

168+
static vm_fault_t xive_native_esb_fault(struct vm_fault *vmf)
169+
{
170+
struct vm_area_struct *vma = vmf->vma;
171+
struct kvm_device *dev = vma->vm_file->private_data;
172+
struct kvmppc_xive *xive = dev->private;
173+
struct kvmppc_xive_src_block *sb;
174+
struct kvmppc_xive_irq_state *state;
175+
struct xive_irq_data *xd;
176+
u32 hw_num;
177+
u16 src;
178+
u64 page;
179+
unsigned long irq;
180+
u64 page_offset;
181+
182+
/*
183+
* Linux/KVM uses a two pages ESB setting, one for trigger and
184+
* one for EOI
185+
*/
186+
page_offset = vmf->pgoff - vma->vm_pgoff;
187+
irq = page_offset / 2;
188+
189+
sb = kvmppc_xive_find_source(xive, irq, &src);
190+
if (!sb) {
191+
pr_devel("%s: source %lx not found !\n", __func__, irq);
192+
return VM_FAULT_SIGBUS;
193+
}
194+
195+
state = &sb->irq_state[src];
196+
kvmppc_xive_select_irq(state, &hw_num, &xd);
197+
198+
arch_spin_lock(&sb->lock);
199+
200+
/*
201+
* first/even page is for trigger
202+
* second/odd page is for EOI and management.
203+
*/
204+
page = page_offset % 2 ? xd->eoi_page : xd->trig_page;
205+
arch_spin_unlock(&sb->lock);
206+
207+
if (WARN_ON(!page)) {
208+
pr_err("%s: acessing invalid ESB page for source %lx !\n",
209+
__func__, irq);
210+
return VM_FAULT_SIGBUS;
211+
}
212+
213+
vmf_insert_pfn(vma, vmf->address, page >> PAGE_SHIFT);
214+
return VM_FAULT_NOPAGE;
215+
}
216+
217+
static const struct vm_operations_struct xive_native_esb_vmops = {
218+
.fault = xive_native_esb_fault,
219+
};
220+
168221
static vm_fault_t xive_native_tima_fault(struct vm_fault *vmf)
169222
{
170223
struct vm_area_struct *vma = vmf->vma;
@@ -194,6 +247,10 @@ static int kvmppc_xive_native_mmap(struct kvm_device *dev,
194247
if (vma_pages(vma) > 4)
195248
return -EINVAL;
196249
vma->vm_ops = &xive_native_tima_vmops;
250+
} else if (vma->vm_pgoff == KVM_XIVE_ESB_PAGE_OFFSET) {
251+
if (vma_pages(vma) > KVMPPC_XIVE_NR_IRQS * 2)
252+
return -EINVAL;
253+
vma->vm_ops = &xive_native_esb_vmops;
197254
} else {
198255
return -EINVAL;
199256
}

0 commit comments

Comments
 (0)