From: Ankit Agrawal <ankita@xxxxxxxxxx> The nvgrace-gpu module tracks the various EGM regions on the system. The EGM region information - Base SPA and size - are part of the ACPI tables. This can be fetched from the DSD table using the GPU handle. When the GPUs are bound to the nvgrace-gpu module, it fetches the EGM region information from the ACPI table using the GPU's pci_dev. The EGM regions are tracked in a list and the information per region is maintained in the nvgrace_egm_dev. Signed-off-by: Ankit Agrawal <ankita@xxxxxxxxxx> --- drivers/vfio/pci/nvgrace-gpu/egm_dev.c | 24 +++++++++++++++++++++++- drivers/vfio/pci/nvgrace-gpu/egm_dev.h | 4 +++- drivers/vfio/pci/nvgrace-gpu/main.c | 8 ++++++-- include/linux/nvgrace-egm.h | 2 ++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/vfio/pci/nvgrace-gpu/egm_dev.c b/drivers/vfio/pci/nvgrace-gpu/egm_dev.c index 28cfd29eda56..ca50bc1f67a0 100644 --- a/drivers/vfio/pci/nvgrace-gpu/egm_dev.c +++ b/drivers/vfio/pci/nvgrace-gpu/egm_dev.c @@ -17,6 +17,26 @@ int nvgrace_gpu_has_egm_property(struct pci_dev *pdev, u64 *pegmpxm) pegmpxm); } +int nvgrace_gpu_fetch_egm_property(struct pci_dev *pdev, u64 *pegmphys, + u64 *pegmlength) +{ + int ret; + + /* + * The memory information is present in the system ACPI tables as DSD + * properties nvidia,egm-base-pa and nvidia,egm-size. + */ + ret = device_property_read_u64(&pdev->dev, "nvidia,egm-size", + pegmlength); + if (ret) + return ret; + + ret = device_property_read_u64(&pdev->dev, "nvidia,egm-base-pa", + pegmphys); + + return ret; +} + int add_gpu(struct nvgrace_egm_dev *egm_dev, struct pci_dev *pdev) { struct gpu_node *node; @@ -54,7 +74,7 @@ static void nvgrace_gpu_release_aux_device(struct device *device) struct nvgrace_egm_dev * nvgrace_gpu_create_aux_device(struct pci_dev *pdev, const char *name, - u64 egmpxm) + u64 egmphys, u64 egmlength, u64 egmpxm) { struct nvgrace_egm_dev *egm_dev; int ret; @@ -64,6 +84,8 @@ nvgrace_gpu_create_aux_device(struct pci_dev *pdev, const char *name, goto create_err; egm_dev->egmpxm = egmpxm; + egm_dev->egmphys = egmphys; + egm_dev->egmlength = egmlength; INIT_LIST_HEAD(&egm_dev->gpus); egm_dev->aux_dev.id = egmpxm; diff --git a/drivers/vfio/pci/nvgrace-gpu/egm_dev.h b/drivers/vfio/pci/nvgrace-gpu/egm_dev.h index 1635753c9e50..2e1612445898 100644 --- a/drivers/vfio/pci/nvgrace-gpu/egm_dev.h +++ b/drivers/vfio/pci/nvgrace-gpu/egm_dev.h @@ -16,6 +16,8 @@ void remove_gpu(struct nvgrace_egm_dev *egm_dev, struct pci_dev *pdev); struct nvgrace_egm_dev * nvgrace_gpu_create_aux_device(struct pci_dev *pdev, const char *name, - u64 egmphys); + u64 egmphys, u64 egmlength, u64 egmpxm); +int nvgrace_gpu_fetch_egm_property(struct pci_dev *pdev, u64 *pegmphys, + u64 *pegmlength); #endif /* EGM_DEV_H */ diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c index 436f0ac17332..7486a1b49275 100644 --- a/drivers/vfio/pci/nvgrace-gpu/main.c +++ b/drivers/vfio/pci/nvgrace-gpu/main.c @@ -67,7 +67,7 @@ static struct list_head egm_dev_list; static int nvgrace_gpu_create_egm_aux_device(struct pci_dev *pdev) { struct nvgrace_egm_dev_entry *egm_entry = NULL; - u64 egmpxm; + u64 egmphys, egmlength, egmpxm; int ret = 0; bool is_new_region = false; @@ -80,6 +80,10 @@ static int nvgrace_gpu_create_egm_aux_device(struct pci_dev *pdev) if (nvgrace_gpu_has_egm_property(pdev, &egmpxm)) goto exit; + ret = nvgrace_gpu_fetch_egm_property(pdev, &egmphys, &egmlength); + if (ret) + goto exit; + list_for_each_entry(egm_entry, &egm_dev_list, list) { /* * A system could have multiple GPUs associated with an @@ -99,7 +103,7 @@ static int nvgrace_gpu_create_egm_aux_device(struct pci_dev *pdev) egm_entry->egm_dev = nvgrace_gpu_create_aux_device(pdev, NVGRACE_EGM_DEV_NAME, - egmpxm); + egmphys, egmlength, egmpxm); if (!egm_entry->egm_dev) { ret = -EINVAL; goto free_egm_entry; diff --git a/include/linux/nvgrace-egm.h b/include/linux/nvgrace-egm.h index e42494a2b1a6..a66906753267 100644 --- a/include/linux/nvgrace-egm.h +++ b/include/linux/nvgrace-egm.h @@ -17,6 +17,8 @@ struct gpu_node { struct nvgrace_egm_dev { struct auxiliary_device aux_dev; + phys_addr_t egmphys; + size_t egmlength; u64 egmpxm; struct list_head gpus; }; -- 2.34.1