@@ -2129,7 +2129,7 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
*/
int pci_mmap_resource_range(struct pci_dev *dev, int bar,
struct vm_area_struct *vma,
- enum pci_mmap_state mmap_state, int write_combine);
+ enum pci_mmap_state mmap_state, int write_combine, int enc);
#ifndef arch_can_pci_mmap_wc
#define arch_can_pci_mmap_wc() 0
@@ -23,7 +23,7 @@ static const struct vm_operations_struct pci_phys_vm_ops = {
int pci_mmap_resource_range(struct pci_dev *pdev, int bar,
struct vm_area_struct *vma,
- enum pci_mmap_state mmap_state, int write_combine)
+ enum pci_mmap_state mmap_state, int write_combine, int enc)
{
unsigned long size;
int ret;
@@ -46,6 +46,15 @@ int pci_mmap_resource_range(struct pci_dev *pdev, int bar,
vma->vm_ops = &pci_phys_vm_ops;
+ /*
+ * Calling remap_pfn_range() directly as io_remap_pfn_range()
+ * enforces shared mapping.
+ */
+ if (enc)
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+
return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
@@ -1062,7 +1062,7 @@ void pci_remove_legacy_files(struct pci_bus *b)
* Use the regular PCI mapping routines to map a PCI resource into userspace.
*/
static int pci_mmap_resource(struct kobject *kobj, const struct bin_attribute *attr,
- struct vm_area_struct *vma, int write_combine)
+ struct vm_area_struct *vma, int write_combine, int enc)
{
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
int bar = (unsigned long)attr->private;
@@ -1082,21 +1082,28 @@ static int pci_mmap_resource(struct kobject *kobj, const struct bin_attribute *a
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
- return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine);
+ return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine, enc);
}
static int pci_mmap_resource_uc(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr,
struct vm_area_struct *vma)
{
- return pci_mmap_resource(kobj, attr, vma, 0);
+ return pci_mmap_resource(kobj, attr, vma, 0, 0);
}
static int pci_mmap_resource_wc(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr,
struct vm_area_struct *vma)
{
- return pci_mmap_resource(kobj, attr, vma, 1);
+ return pci_mmap_resource(kobj, attr, vma, 1, 0);
+}
+
+static int pci_mmap_resource_enc(struct file *filp, struct kobject *kobj,
+ const struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ return pci_mmap_resource(kobj, attr, vma, 0, 1);
}
static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
@@ -1190,7 +1197,7 @@ static void pci_remove_resource_files(struct pci_dev *pdev)
}
}
-static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine, int enc)
{
/* allocate attribute structure, piggyback attribute name */
int name_len = write_combine ? 13 : 10;
@@ -1208,6 +1215,9 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
if (write_combine) {
sprintf(res_attr_name, "resource%d_wc", num);
res_attr->mmap = pci_mmap_resource_wc;
+ } else if (enc) {
+ sprintf(res_attr_name, "resource%d_enc", num);
+ res_attr->mmap = pci_mmap_resource_enc;
} else {
sprintf(res_attr_name, "resource%d", num);
if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
@@ -1264,11 +1274,14 @@ static int pci_create_resource_files(struct pci_dev *pdev)
if (!pci_resource_len(pdev, i))
continue;
- retval = pci_create_attr(pdev, i, 0);
+ retval = pci_create_attr(pdev, i, 0, 0);
/* for prefetchable resources, create a WC mappable file */
if (!retval && arch_can_pci_mmap_wc() &&
pdev->resource[i].flags & IORESOURCE_PREFETCH)
- retval = pci_create_attr(pdev, i, 1);
+ retval = pci_create_attr(pdev, i, 1, 0);
+ /* Add node for private MMIO mapping */
+ if (!retval)
+ retval = pci_create_attr(pdev, i, 0, 1);
if (retval) {
pci_remove_resource_files(pdev);
return retval;
@@ -284,7 +284,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
/* Adjust vm_pgoff to be the offset within the resource */
vma->vm_pgoff -= start >> PAGE_SHIFT;
ret = pci_mmap_resource_range(dev, i, vma,
- fpriv->mmap_state, write_combine);
+ fpriv->mmap_state, write_combine, 0);
if (ret < 0)
return ret;
Add another resource#d_enc to allow mapping MMIO as an encrypted/private region. Unlike resourceN_wc, the node is added always as ability to map MMIO as private depends on negotiation with the TSM which happens quite late. Signed-off-by: Alexey Kardashevskiy <aik@amd.com> --- include/linux/pci.h | 2 +- drivers/pci/mmap.c | 11 +++++++- drivers/pci/pci-sysfs.c | 27 +++++++++++++++----- drivers/pci/proc.c | 2 +- 4 files changed, 32 insertions(+), 10 deletions(-)