Skip to content

Commit

Permalink
drm/xen: Major refactoring towards upstream
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksandr Andrushchenko <[email protected]>
  • Loading branch information
Oleksandr Andrushchenko authored and iartemenko committed Dec 18, 2017
1 parent fd883ca commit a9f4fe4
Show file tree
Hide file tree
Showing 28 changed files with 2,417 additions and 1,836 deletions.
7 changes: 7 additions & 0 deletions drivers/gpu/drm/xen/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ config DRM_XEN
Choose this option if you want to enable DRM support
for Xen.

choice
prompt "DRM driver sub-type selection"
depends on DRM_XEN

config DRM_XEN_FRONTEND
tristate "Front-end paravirtualized driver for Xen guest OS"
depends on DRM_XEN
Expand Down Expand Up @@ -60,3 +64,6 @@ config DRM_XEN_ZCOPY_CMA
This is only available for built-in driver, because
there is a dependency on DMA ops which are only available
for built-in code.

endchoice

13 changes: 8 additions & 5 deletions drivers/gpu/drm/xen/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.

drm_xen_front-objs := xen_drm_front.o xen_drm_drv.o xen_drm_kms.o xen_drm_crtc.o \
xen_drm_timer.o xen_drm_shbuf.o
drm_xen_front-objs := xen_drm_front.o xen_drm_front_drv.o xen_drm_front_kms.o \
xen_drm_front_crtc.o xen_drm_front_timer.o xen_drm_front_shbuf.o \
xen_drm_balloon.o xen_drm_front_evtchnl.o xen_drm_front_cfg.o

ifneq ($(CONFIG_DRM_XEN_FRONTEND_CMA),y)
drm_xen_front-objs += xen_drm_gem.o
ifeq ($(CONFIG_DRM_XEN_FRONTEND_CMA),y)
drm_xen_front-objs += xen_drm_front_gem_cma.o
else
drm_xen_front-objs += xen_drm_front_gem.o
endif

obj-$(CONFIG_DRM_XEN_FRONTEND) += drm_xen_front.o

drm_xen_zcopy-objs := xen_drm_zcopy_drv.o
drm_xen_zcopy-objs := xen_drm_zcopy_drv.o xen_drm_balloon.o

obj-$(CONFIG_DRM_XEN_ZCOPY) += drm_xen_zcopy.o
154 changes: 154 additions & 0 deletions drivers/gpu/drm/xen/xen_drm_balloon.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Xen para-virtual DRM device
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2016-2017 EPAM Systems Inc.
*
* Author: Oleksandr Andrushchenko <[email protected]>
*/

#include <drm/drmP.h>

#if defined(CONFIG_DRM_XEN_ZCOPY_CMA)
#include <asm/xen/hypercall.h>
#include <xen/interface/memory.h>
#include <xen/page.h>
#else
#include <xen/balloon.h>
#endif

#include "xen_drm_balloon.h"

#if defined(CONFIG_DRM_XEN_ZCOPY_CMA)
int xen_drm_ballooned_pages_alloc(struct device *dev,
struct xen_drm_balloon *obj, int num_pages, struct page **pages)
{
xen_pfn_t *frame_list;
size_t size;
int i, ret;
dma_addr_t dev_addr, cpu_addr;
void *vaddr = NULL;
struct xen_memory_reservation reservation = {
.address_bits = 0,
.extent_order = 0,
.domid = DOMID_SELF
};

size = num_pages * PAGE_SIZE;
DRM_DEBUG("Ballooning out %d pages, size %zu\n", num_pages, size);
frame_list = kcalloc(num_pages, sizeof(*frame_list), GFP_KERNEL);
if (!frame_list)
return -ENOMEM;

vaddr = dma_alloc_wc(dev, size, &dev_addr, GFP_KERNEL | __GFP_NOWARN);
if (!vaddr) {
DRM_ERROR("Failed to allocate DMA buffer with size %zu\n",
size);
ret = -ENOMEM;
goto fail;
}

cpu_addr = dev_addr;
for (i = 0; i < num_pages; i++) {
pages[i] = pfn_to_page(__phys_to_pfn(cpu_addr));
/* XENMEM_populate_physmap requires a PFN based on Xen
* granularity.
*/
frame_list[i] = page_to_xen_pfn(pages[i]);
cpu_addr += PAGE_SIZE;
}
set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = num_pages;
/* rc will hold number of pages processed */
ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
if (ret <= 0) {
DRM_ERROR("Failed to balloon out %d pages (%d), retrying\n",
num_pages, ret);
WARN_ON(ret != num_pages);
ret = -EFAULT;
goto fail;
}

obj->vaddr = vaddr;
obj->dev_bus_addr = dev_addr;
kfree(frame_list);
return 0;

fail:
if (vaddr)
dma_free_wc(dev, size, vaddr, dev_addr);
kfree(frame_list);
return ret;
}

void xen_drm_ballooned_pages_free(struct device *dev,
struct xen_drm_balloon *obj, int num_pages, struct page **pages)
{
xen_pfn_t *frame_list;
int i, ret;
size_t size;
struct xen_memory_reservation reservation = {
.address_bits = 0,
.extent_order = 0,
.domid = DOMID_SELF
};

if (!pages)
return;

if (!obj->vaddr)
return;

frame_list = kcalloc(num_pages, sizeof(*frame_list), GFP_KERNEL);
if (!frame_list) {
DRM_ERROR("Failed to balloon in %d pages\n", num_pages);
return;
}

DRM_DEBUG("Ballooning in %d pages\n", num_pages);
size = num_pages * PAGE_SIZE;
for (i = 0; i < num_pages; i++) {
/*
* XENMEM_populate_physmap requires a PFN based on Xen
* granularity.
*/
frame_list[i] = page_to_xen_pfn(pages[i]);
}
set_xen_guest_handle(reservation.extent_start, frame_list);
reservation.nr_extents = num_pages;
/* rc will hold number of pages processed */
ret = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
if (ret <= 0) {
DRM_ERROR("Failed to balloon in %d pages\n", num_pages);
WARN_ON(ret != num_pages);
}

if (obj->vaddr)
dma_free_wc(dev, size, obj->vaddr, obj->dev_bus_addr);

obj->vaddr = NULL;
obj->dev_bus_addr = 0;
kfree(frame_list);
}
#else
int xen_drm_ballooned_pages_alloc(struct device *dev,
struct xen_drm_balloon *obj, int num_pages, struct page **pages)
{
return alloc_xenballooned_pages(num_pages, pages);
}

void xen_drm_ballooned_pages_free(struct device *dev,
struct xen_drm_balloon *obj, int num_pages, struct page **pages)
{
free_xenballooned_pages(num_pages, pages);
}
#endif /* defined(CONFIG_DRM_XEN_ZCOPY_CMA) */
36 changes: 36 additions & 0 deletions drivers/gpu/drm/xen/xen_drm_balloon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Xen para-virtual DRM device
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2016-2017 EPAM Systems Inc.
*
* Author: Oleksandr Andrushchenko <[email protected]>
*/

#ifndef __XEN_DRM_BALLOON_H_
#define __XEN_DRM_BALLOON_H_

#define GRANT_INVALID_REF 0

#include <linux/types.h>

struct xen_drm_balloon {
void *vaddr;
dma_addr_t dev_bus_addr;
};

int xen_drm_ballooned_pages_alloc(struct device *dev,
struct xen_drm_balloon *obj, int num_pages, struct page **pages);
void xen_drm_ballooned_pages_free(struct device *dev,
struct xen_drm_balloon *obj,int num_pages, struct page **pages);

#endif /* __XEN_DRM_BALLOON_H_ */
Loading

0 comments on commit a9f4fe4

Please sign in to comment.