Skip to content

Commit 39e9af3

Browse files
legoaterpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Add a TIMA mapping
Each thread has an associated Thread Interrupt Management context composed of a set of registers. These registers let the thread handle priority management and interrupt acknowledgment. The most important are : - Interrupt Pending Buffer (IPB) - Current Processor Priority (CPPR) - Notification Source Register (NSR) They are exposed to software in four different pages each proposing a view with a different privilege. The first page is for the physical thread context and the second for the hypervisor. Only the third (operating system) and the fourth (user level) are exposed the guest. A custom VM fault handler will populate the VMA with the appropriate pages, which should only be the OS page for now. Signed-off-by: Cédric Le Goater <[email protected]> Reviewed-by: David Gibson <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent a1cd3f0 commit 39e9af3

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

Documentation/virtual/kvm/devices/xive.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,29 @@ requires a POWER9 host and the guest OS should have support for the
1313
XIVE native exploitation interrupt mode. If not, it should run using
1414
the legacy interrupt mode, referred as XICS (POWER7/8).
1515

16+
* Device Mappings
17+
18+
The KVM device exposes different MMIO ranges of the XIVE HW which
19+
are required for interrupt management. These are exposed to the
20+
guest in VMAs populated with a custom VM fault handler.
21+
22+
1. Thread Interrupt Management Area (TIMA)
23+
24+
Each thread has an associated Thread Interrupt Management context
25+
composed of a set of registers. These registers let the thread
26+
handle priority management and interrupt acknowledgment. The most
27+
important are :
28+
29+
- Interrupt Pending Buffer (IPB)
30+
- Current Processor Priority (CPPR)
31+
- Notification Source Register (NSR)
32+
33+
They are exposed to software in four different pages each proposing
34+
a view with a different privilege. The first page is for the
35+
physical thread context and the second for the hypervisor. Only the
36+
third (operating system) and the fourth (user level) are exposed the
37+
guest.
38+
1639
* Groups:
1740

1841
1. KVM_DEV_XIVE_GRP_CTRL

arch/powerpc/include/asm/xive.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* same offset regardless of where the code is executing
2424
*/
2525
extern void __iomem *xive_tima;
26+
extern unsigned long xive_tima_os;
2627

2728
/*
2829
* Offset in the TM area of our current execution level (provided by

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,4 +720,6 @@ struct kvm_ppc_xive_eq {
720720

721721
#define KVM_XIVE_EQ_ALWAYS_NOTIFY 0x00000001
722722

723+
#define KVM_XIVE_TIMA_PAGE_OFFSET 0
724+
723725
#endif /* __LINUX_KVM_POWERPC_H */

arch/powerpc/kvm/book3s_xive_native.c

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

168+
static vm_fault_t xive_native_tima_fault(struct vm_fault *vmf)
169+
{
170+
struct vm_area_struct *vma = vmf->vma;
171+
172+
switch (vmf->pgoff - vma->vm_pgoff) {
173+
case 0: /* HW - forbid access */
174+
case 1: /* HV - forbid access */
175+
return VM_FAULT_SIGBUS;
176+
case 2: /* OS */
177+
vmf_insert_pfn(vma, vmf->address, xive_tima_os >> PAGE_SHIFT);
178+
return VM_FAULT_NOPAGE;
179+
case 3: /* USER - TODO */
180+
default:
181+
return VM_FAULT_SIGBUS;
182+
}
183+
}
184+
185+
static const struct vm_operations_struct xive_native_tima_vmops = {
186+
.fault = xive_native_tima_fault,
187+
};
188+
189+
static int kvmppc_xive_native_mmap(struct kvm_device *dev,
190+
struct vm_area_struct *vma)
191+
{
192+
/* We only allow mappings at fixed offset for now */
193+
if (vma->vm_pgoff == KVM_XIVE_TIMA_PAGE_OFFSET) {
194+
if (vma_pages(vma) > 4)
195+
return -EINVAL;
196+
vma->vm_ops = &xive_native_tima_vmops;
197+
} else {
198+
return -EINVAL;
199+
}
200+
201+
vma->vm_flags |= VM_IO | VM_PFNMAP;
202+
vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot);
203+
return 0;
204+
}
205+
168206
static int kvmppc_xive_native_set_source(struct kvmppc_xive *xive, long irq,
169207
u64 addr)
170208
{
@@ -1050,6 +1088,7 @@ struct kvm_device_ops kvm_xive_native_ops = {
10501088
.set_attr = kvmppc_xive_native_set_attr,
10511089
.get_attr = kvmppc_xive_native_get_attr,
10521090
.has_attr = kvmppc_xive_native_has_attr,
1091+
.mmap = kvmppc_xive_native_mmap,
10531092
};
10541093

10551094
void kvmppc_xive_native_init_module(void)

arch/powerpc/sysdev/xive/native.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ u32 xive_native_default_eq_shift(void)
521521
}
522522
EXPORT_SYMBOL_GPL(xive_native_default_eq_shift);
523523

524+
unsigned long xive_tima_os;
525+
EXPORT_SYMBOL_GPL(xive_tima_os);
526+
524527
bool __init xive_native_init(void)
525528
{
526529
struct device_node *np;
@@ -573,6 +576,14 @@ bool __init xive_native_init(void)
573576
for_each_possible_cpu(cpu)
574577
kvmppc_set_xive_tima(cpu, r.start, tima);
575578

579+
/* Resource 2 is OS window */
580+
if (of_address_to_resource(np, 2, &r)) {
581+
pr_err("Failed to get thread mgmnt area resource\n");
582+
return false;
583+
}
584+
585+
xive_tima_os = r.start;
586+
576587
/* Grab size of provisionning pages */
577588
xive_parse_provisioning(np);
578589

0 commit comments

Comments
 (0)