Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bb32a44 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm/arm64: Keep GICv2 HYP VAs in kvm_vgic_global_state



As we're about to change the way we map devices at HYP, we need
to move away from kern_hyp_va on an IO address.

One way of achieving this is to store the VAs in kvm_vgic_global_state,
and use that directly from the HYP code. This requires a small change
to create_hyp_io_mappings so that it can also return a HYP VA.

We take this opportunity to nuke the vctrl_base field in the emulated
distributor, as it is not used anymore.

Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 807a3784
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@

int create_hyp_mappings(void *from, void *to, pgprot_t prot);
int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
			   void __iomem **kaddr);
			   void __iomem **kaddr,
			   void __iomem **haddr);
void free_hyp_pgds(void);

void stage2_unmap_vm(struct kvm *kvm);
+2 −1
Original line number Diff line number Diff line
@@ -141,7 +141,8 @@ static inline unsigned long __kern_hyp_va(unsigned long v)

int create_hyp_mappings(void *from, void *to, pgprot_t prot);
int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
			   void __iomem **kaddr);
			   void __iomem **kaddr,
			   void __iomem **haddr);
void free_hyp_pgds(void);

void stage2_unmap_vm(struct kvm *kvm);
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu)
		return -1;

	rd = kvm_vcpu_dabt_get_rd(vcpu);
	addr  = kern_hyp_va(hyp_symbol_addr(kvm_vgic_global_state)->vcpu_base_va);
	addr  = hyp_symbol_addr(kvm_vgic_global_state)->vcpu_hyp_va;
	addr += fault_ipa - vgic->vgic_cpu_base;

	if (kvm_vcpu_dabt_iswrite(vcpu)) {
+6 −6
Original line number Diff line number Diff line
@@ -57,11 +57,15 @@ struct vgic_global {
	/* Physical address of vgic virtual cpu interface */
	phys_addr_t		vcpu_base;

	/* GICV mapping */
	/* GICV mapping, kernel VA */
	void __iomem		*vcpu_base_va;
	/* GICV mapping, HYP VA */
	void __iomem		*vcpu_hyp_va;

	/* virtual control interface mapping */
	/* virtual control interface mapping, kernel VA */
	void __iomem		*vctrl_base;
	/* virtual control interface mapping, HYP VA */
	void __iomem		*vctrl_hyp;

	/* Number of implemented list registers */
	int			nr_lr;
@@ -209,10 +213,6 @@ struct vgic_dist {

	int			nr_spis;

	/* TODO: Consider moving to global state */
	/* Virtual control interface mapping */
	void __iomem		*vctrl_base;

	/* base addresses in guest physical address space: */
	gpa_t			vgic_dist_base;		/* distributor */
	union {
+15 −5
Original line number Diff line number Diff line
@@ -713,28 +713,38 @@ int create_hyp_mappings(void *from, void *to, pgprot_t prot)
 * @phys_addr:	The physical start address which gets mapped
 * @size:	Size of the region being mapped
 * @kaddr:	Kernel VA for this mapping
 *
 * The resulting HYP VA is the same as the kernel VA, modulo
 * HYP_PAGE_OFFSET.
 * @haddr:	HYP VA for this mapping
 */
int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
			   void __iomem **kaddr)
			   void __iomem **kaddr,
			   void __iomem **haddr)
{
	unsigned long start, end;
	int ret;

	*kaddr = ioremap(phys_addr, size);
	if (!*kaddr)
		return -ENOMEM;

	if (is_kernel_in_hyp_mode()) {
		*haddr = *kaddr;
		return 0;
	}


	start = kern_hyp_va((unsigned long)*kaddr);
	end = kern_hyp_va((unsigned long)*kaddr + size);
	return __create_hyp_mappings(hyp_pgd, PTRS_PER_PGD, start, end,
	ret = __create_hyp_mappings(hyp_pgd, PTRS_PER_PGD, start, end,
				     __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE);

	if (ret) {
		iounmap(*kaddr);
		*kaddr = NULL;
		return ret;
	}

	*haddr = (void __iomem *)start;
	return 0;
}

/**
Loading