<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Calibri;font-size:10pt;color:#0000FF;margin:5pt;font-style:normal;font-weight:normal;text-decoration:none;" align="Left">
[AMD Official Use Only - AMD Internal Distribution Only]<br>
</p>
<br>
<div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Hi Hawking,</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
We still use the BM CPER ring (through amdgpu_cper_ring_write) but as SRIOV requires an extra step to query the CPERs, we created a new function amdgpu_debugfs_virt_ring_read within amdgpu_debugfs_virt_ring_fops that does exactly that. It is separate to avoid
 affecting the BM hot path with any extraneous calculations. The debugfs is exactly the same (amdgpu_ring_cper).</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
Thanks, Tony</div>
<div id="appendonsend"></div>
<div style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);">
<br>
</div>
<hr style="display: inline-block; width: 98%;">
<div dir="ltr" id="divRplyFwdMsg"><span style="font-family: Calibri, sans-serif; font-size: 11pt; color: rgb(0, 0, 0);"><b>From:</b> Zhang, Hawking <Hawking.Zhang@amd.com><br>
<b>Sent:</b> Friday, February 28, 2025 1:00 AM<br>
<b>To:</b> Yi, Tony <Tony.Yi@amd.com>; Skvortsov, Victor <Victor.Skvortsov@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; Luo, Zhigang <Zhigang.Luo@amd.com>; Liu, Xiang(Dean) <Xiang.Liu@amd.com>; Zhou1, Tao <Tao.Zhou1@amd.com><br>
<b>Subject:</b> RE: [PATCH 2/2] drm/amdgpu: Add support for CPERs on virtualization</span>
<div> </div>
</div>
<div style="padding-right: 5pt; padding-left: 5pt; font-family: Calibri; font-size: 10pt; color: blue;">
[AMD Official Use Only - AMD Internal Distribution Only]</div>
<div style="margin-top: 5pt; font-family: "Times New Roman"; font-size: 12pt;"><br>
</div>
<div style="font-family: Calibri; font-size: 11pt;">+ <span style="color: rgb(43, 87, 154); background-color: rgb(225, 223, 221);">
<a href="mailto:Xiang.Liu@amd.com" id="OWA1df899a8-7bf4-ecdd-64e9-17cfc0009953" class="OWAAutoLink">@Liu, Xiang(Dean)</a></span>/<span style="color: rgb(43, 87, 154); background-color: rgb(225, 223, 221);"><a href="mailto:Tao.Zhou1@amd.com" id="OWA6b502cbc-55b1-92c3-21fc-2ca5e697645e" class="OWAAutoLink">@Zhou1,
 Tao</a></span> for the code review</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (amdgpu_sriov_vf(adev))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               debugfs_create_file_size(name, S_IFREG | 0444, root, ring,</div>
<div class="elementToProof" style="font-family: Calibri; font-size: 11pt;">+                                        &amdgpu_debugfs_virt_ring_fops,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        ring->ring_size + 12);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       else</div>
<div style="font-family: Calibri; font-size: 11pt;">+               debugfs_create_file_size(name, S_IFREG | 0444, root, ring,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        &amdgpu_debugfs_ring_fops,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        ring->ring_size + 12);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">Hi Tony,</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">Is there any reason the VF requires a separate file system node? Is it because the VF has its own CPER ring? If so, can you please check if the VF can reuse the CPER created for bare-metal?</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">Regards,</div>
<div style="font-family: Calibri; font-size: 11pt;">Hawking</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">-----Original Message-----<br>
From: Yi, Tony <Tony.Yi@amd.com><br>
Sent: Thursday, February 27, 2025 23:12<br>
To: Yi, Tony <Tony.Yi@amd.com>; Skvortsov, Victor <Victor.Skvortsov@amd.com>; amd-gfx@lists.freedesktop.org; Zhang, Hawking <Hawking.Zhang@amd.com>; Luo, Zhigang <Zhigang.Luo@amd.com><br>
Cc: Yi, Tony <Tony.Yi@amd.com><br>
Subject: [PATCH 2/2] drm/amdgpu: Add support for CPERs on virtualization</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">Add support for CPERs on VFs.</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">VFs do not receive PMFW messages directly; as such, they need to query them from the host. To avoid hitting host event guard, CPER queries need to be rate limited. CPER queries share the same RAS telemetry
 buffer as error count query, so a mutex protecting the shared buffer was added as well.</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">For readability, the amdgpu_detect_virtualization was refactored into multiple individual functions.</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">Signed-off-by: Tony Yi <<a href="mailto:Tony.Yi@amd.com" id="OWA73f6103f-22ac-d1b5-97da-49447c7d8667" class="OWAAutoLink">Tony.Yi@amd.com</a>></div>
<div style="font-family: Calibri; font-size: 11pt;">---</div>
<div style="font-family: Calibri; font-size: 11pt;">drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   7 +-</div>
<div style="font-family: Calibri; font-size: 11pt;">drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c   |  31 ++++-</div>
<div style="font-family: Calibri; font-size: 11pt;">drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c   | 138 ++++++++++++++++++++-</div>
<div style="font-family: Calibri; font-size: 11pt;">drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h   |  18 ++-</div>
<div style="font-family: Calibri; font-size: 11pt;">drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c      |  14 +++</div>
<div style="font-family: Calibri; font-size: 11pt;">5 files changed, 195 insertions(+), 13 deletions(-)</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c</div>
<div style="font-family: Calibri; font-size: 11pt;">index 5e1d8f0039d0..198d29faa754 100644</div>
<div style="font-family: Calibri; font-size: 11pt;">--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c</div>
<div style="font-family: Calibri; font-size: 11pt;">+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -3099,7 +3099,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         amdgpu_fru_get_product_info(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">-       r = amdgpu_cper_init(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (!amdgpu_sriov_vf(adev) || amdgpu_sriov_ras_cper_en(adev))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               r = amdgpu_cper_init(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">init_failed:</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -4335,10 +4336,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">          * for throttling interrupt) = 60 seconds.</div>
<div style="font-family: Calibri; font-size: 11pt;">          */</div>
<div style="font-family: Calibri; font-size: 11pt;">         ratelimit_state_init(&adev->throttling_logging_rs, (60 - 1) * HZ, 1);</div>
<div style="font-family: Calibri; font-size: 11pt;">-       ratelimit_state_init(&adev->virt.ras_telemetry_rs, 5 * HZ, 1);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         ratelimit_set_flags(&adev->throttling_logging_rs, RATELIMIT_MSG_ON_RELEASE);</div>
<div style="font-family: Calibri; font-size: 11pt;">-       ratelimit_set_flags(&adev->virt.ras_telemetry_rs, RATELIMIT_MSG_ON_RELEASE);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         /* Registers mapping */</div>
<div style="font-family: Calibri; font-size: 11pt;">         /* TODO: block userspace mapping of io register */ @@ -4370,7 +4369,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">                 return -ENOMEM;</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         /* detect hw virtualization here */</div>
<div style="font-family: Calibri; font-size: 11pt;">-       amdgpu_detect_virtualization(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       amdgpu_virt_init(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         amdgpu_device_get_pcie_info(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c</div>
<div style="font-family: Calibri; font-size: 11pt;">index 81a7d4faac9c..d55c8b7fdb59 100644</div>
<div style="font-family: Calibri; font-size: 11pt;">--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c</div>
<div style="font-family: Calibri; font-size: 11pt;">+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -578,12 +578,32 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,</div>
<div style="font-family: Calibri; font-size: 11pt;">         return result;</div>
<div style="font-family: Calibri; font-size: 11pt;">}</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+static ssize_t amdgpu_debugfs_virt_ring_read(struct file *f, char __user *buf,</div>
<div style="font-family: Calibri; font-size: 11pt;">+       size_t size, loff_t *pos)</div>
<div style="font-family: Calibri; font-size: 11pt;">+{</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amdgpu_ring *ring = file_inode(f)->i_private;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (*pos & 3 || size & 3)</div>
<div style="font-family: Calibri; font-size: 11pt;">+               return -EINVAL;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)</div>
<div style="font-family: Calibri; font-size: 11pt;">+               amdgpu_virt_req_ras_cper_dump(ring->adev, false);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return amdgpu_debugfs_ring_read(f, buf, size, pos); }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">static const struct file_operations amdgpu_debugfs_ring_fops = {</div>
<div style="font-family: Calibri; font-size: 11pt;">         .owner = THIS_MODULE,</div>
<div style="font-family: Calibri; font-size: 11pt;">         .read = amdgpu_debugfs_ring_read,</div>
<div style="font-family: Calibri; font-size: 11pt;">         .llseek = default_llseek</div>
<div style="font-family: Calibri; font-size: 11pt;">};</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+static const struct file_operations amdgpu_debugfs_virt_ring_fops = {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       .owner = THIS_MODULE,</div>
<div style="font-family: Calibri; font-size: 11pt;">+       .read = amdgpu_debugfs_virt_ring_read,</div>
<div style="font-family: Calibri; font-size: 11pt;">+       .llseek = default_llseek</div>
<div style="font-family: Calibri; font-size: 11pt;">+};</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">static ssize_t amdgpu_debugfs_mqd_read(struct file *f, char __user *buf,</div>
<div style="font-family: Calibri; font-size: 11pt;">                                        size_t size, loff_t *pos)</div>
<div style="font-family: Calibri; font-size: 11pt;">{</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -671,9 +691,14 @@ void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">         char name[32];</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         sprintf(name, "amdgpu_ring_%s", ring->name);</div>
<div style="font-family: Calibri; font-size: 11pt;">-       debugfs_create_file_size(name, S_IFREG | 0444, root, ring,</div>
<div style="font-family: Calibri; font-size: 11pt;">-                                &amdgpu_debugfs_ring_fops,</div>
<div style="font-family: Calibri; font-size: 11pt;">-                                ring->ring_size + 12);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (amdgpu_sriov_vf(adev))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               debugfs_create_file_size(name, S_IFREG | 0444, root, ring,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        &amdgpu_debugfs_virt_ring_fops,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        ring->ring_size + 12);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       else</div>
<div style="font-family: Calibri; font-size: 11pt;">+               debugfs_create_file_size(name, S_IFREG | 0444, root, ring,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        &amdgpu_debugfs_ring_fops,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                        ring->ring_size + 12);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         if (ring->mqd_obj) {</div>
<div style="font-family: Calibri; font-size: 11pt;">                 sprintf(name, "amdgpu_mqd_%s", ring->name); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c</div>
<div style="font-family: Calibri; font-size: 11pt;">index e6f0152e5b08..3832513ec7bf 100644</div>
<div style="font-family: Calibri; font-size: 11pt;">--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c</div>
<div style="font-family: Calibri; font-size: 11pt;">+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -739,7 +739,7 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">         }</div>
<div style="font-family: Calibri; font-size: 11pt;">}</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">-void amdgpu_detect_virtualization(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">+static u32 amdgpu_virt_init_detect_asic(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">{</div>
<div style="font-family: Calibri; font-size: 11pt;">         uint32_t reg;</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -775,8 +775,17 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">                         adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;</div>
<div style="font-family: Calibri; font-size: 11pt;">         }</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+       return reg;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+static bool amdgpu_virt_init_req_data(struct amdgpu_device *adev, u32</div>
<div style="font-family: Calibri; font-size: 11pt;">+reg) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       bool is_sriov = false;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">         /* we have the ability to check now */</div>
<div style="font-family: Calibri; font-size: 11pt;">         if (amdgpu_sriov_vf(adev)) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               is_sriov = true;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">                 switch (adev->asic_type) {</div>
<div style="font-family: Calibri; font-size: 11pt;">                 case CHIP_TONGA:</div>
<div style="font-family: Calibri; font-size: 11pt;">                 case CHIP_FIJI:</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -805,10 +814,39 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">                         amdgpu_virt_request_init_data(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">                         break;</div>
<div style="font-family: Calibri; font-size: 11pt;">                 default: /* other chip doesn't support SRIOV */</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       is_sriov = false;</div>
<div style="font-family: Calibri; font-size: 11pt;">                         DRM_ERROR("Unknown asic type: %d!\n", adev->asic_type);</div>
<div style="font-family: Calibri; font-size: 11pt;">                         break;</div>
<div style="font-family: Calibri; font-size: 11pt;">                 }</div>
<div style="font-family: Calibri; font-size: 11pt;">         }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return is_sriov;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+static void amdgpu_virt_init_ras(struct amdgpu_device *adev) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       ratelimit_state_init(&adev->virt.ras.ras_error_cnt_rs, 5 * HZ, 1);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       ratelimit_state_init(&adev->virt.ras.ras_cper_dump_rs, 5 * HZ, 1);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       ratelimit_set_flags(&adev->virt.ras.ras_error_cnt_rs,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                           RATELIMIT_MSG_ON_RELEASE);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       ratelimit_set_flags(&adev->virt.ras.ras_cper_dump_rs,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                           RATELIMIT_MSG_ON_RELEASE);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       mutex_init(&adev->virt.ras.ras_telemetry_mutex);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       adev->virt.ras.cper_rptr = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+void amdgpu_virt_init(struct amdgpu_device *adev) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       bool is_sriov = false;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       uint32_t reg = amdgpu_virt_init_detect_asic(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       is_sriov = amdgpu_virt_init_req_data(adev, reg);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (is_sriov)</div>
<div style="font-family: Calibri; font-size: 11pt;">+               amdgpu_virt_init_ras(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">}</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">static bool amdgpu_virt_access_debugfs_is_mmio(struct amdgpu_device *adev) @@ -1288,10 +1326,12 @@ static int amdgpu_virt_req_ras_err_count_internal(struct amdgpu_device *adev, bo</div>
<div style="font-family: Calibri; font-size: 11pt;">          * will ignore incoming guest messages. Ratelimit the guest messages to</div>
<div style="font-family: Calibri; font-size: 11pt;">          * prevent guest self DOS.</div>
<div style="font-family: Calibri; font-size: 11pt;">          */</div>
<div style="font-family: Calibri; font-size: 11pt;">-       if (__ratelimit(&adev->virt.ras_telemetry_rs) || force_update) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (__ratelimit(&virt->ras.ras_error_cnt_rs) || force_update) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               mutex_lock(&virt->ras.ras_telemetry_mutex);</div>
<div style="font-family: Calibri; font-size: 11pt;">                 if (!virt->ops->req_ras_err_count(adev))</div>
<div style="font-family: Calibri; font-size: 11pt;">                         amdgpu_virt_cache_host_error_counts(adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">-                               adev->virt.fw_reserve.ras_telemetry);</div>
<div style="font-family: Calibri; font-size: 11pt;">+                               virt->fw_reserve.ras_telemetry);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               mutex_unlock(&virt->ras.ras_telemetry_mutex);</div>
<div style="font-family: Calibri; font-size: 11pt;">         }</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         return 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -1322,6 +1362,98 @@ int amdgpu_virt_req_ras_err_count(struct amdgpu_device *adev, enum amdgpu_ras_bl</div>
<div style="font-family: Calibri; font-size: 11pt;">         return 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">}</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+static int</div>
<div style="font-family: Calibri; font-size: 11pt;">+amdgpu_virt_write_cpers_to_ring(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                               struct amdsriov_ras_telemetry *host_telemetry,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                               u32 *more)</div>
<div style="font-family: Calibri; font-size: 11pt;">+{</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amd_sriov_ras_cper_dump *cper_dump = NULL;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct cper_hdr *entry = NULL;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amdgpu_ring *ring = &adev->cper.ring_buf;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       uint32_t checksum, used_size, i, j;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       int ret = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       checksum = host_telemetry->header.checksum;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       used_size = host_telemetry->header.used_size;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (used_size > (AMD_SRIOV_RAS_TELEMETRY_SIZE_KB << 10))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               return 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       cper_dump = kmemdup(&host_telemetry->body.cper_dump, used_size, GFP_KERNEL);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (!cper_dump)</div>
<div style="font-family: Calibri; font-size: 11pt;">+               return -ENOMEM;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (checksum != amd_sriov_msg_checksum(cper_dump, used_size, 0, 0))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               goto out;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       *more = cper_dump->more;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (cper_dump->wptr < adev->virt.ras.cper_rptr) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               dev_warn(</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       adev->dev,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       "guest specified rptr that was too high! guest rptr: 0x%llx, host rptr: 0x%llx\n",</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       adev->virt.ras.cper_rptr, cper_dump->wptr);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+               adev->virt.ras.cper_rptr = cper_dump->wptr;</div>
<div style="font-family: Calibri; font-size: 11pt;">+               goto out;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       entry = (struct cper_hdr *)&cper_dump->buf[0];</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       for (i = 0; i < cper_dump->count; i++) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               amdgpu_cper_ring_write(ring, entry, entry->record_length);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               entry = (struct cper_hdr *)((char *)entry +</div>
<div style="font-family: Calibri; font-size: 11pt;">+                                           entry->record_length);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (cper_dump->overflow_count)</div>
<div style="font-family: Calibri; font-size: 11pt;">+               dev_warn(adev->dev,</div>
<div style="font-family: Calibri; font-size: 11pt;">+                        "host reported CPER overflow of 0x%llx entries!\n",</div>
<div style="font-family: Calibri; font-size: 11pt;">+                        cper_dump->overflow_count);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       adev->virt.ras.cper_rptr = cper_dump->wptr;</div>
<div style="font-family: Calibri; font-size: 11pt;">+out:</div>
<div style="font-family: Calibri; font-size: 11pt;">+       kfree(cper_dump);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return ret;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+static int amdgpu_virt_req_ras_cper_dump_internal(struct amdgpu_device</div>
<div style="font-family: Calibri; font-size: 11pt;">+*adev) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amdgpu_virt *virt = &adev->virt;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       int ret = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       uint32_t more = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if (!amdgpu_sriov_ras_cper_en(adev))</div>
<div style="font-family: Calibri; font-size: 11pt;">+               return -EOPNOTSUPP;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       do {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               if (!virt->ops->req_ras_cper_dump(adev, virt->ras.cper_rptr))</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       ret = amdgpu_virt_write_cpers_to_ring(</div>
<div style="font-family: Calibri; font-size: 11pt;">+                               adev, virt->fw_reserve.ras_telemetry, &more);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               else</div>
<div style="font-family: Calibri; font-size: 11pt;">+                       ret = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       } while (more);</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return ret;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+int amdgpu_virt_req_ras_cper_dump(struct amdgpu_device *adev, bool</div>
<div style="font-family: Calibri; font-size: 11pt;">+force_update) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amdgpu_virt *virt = &adev->virt;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       int ret = 0;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       if ((__ratelimit(&virt->ras.ras_cper_dump_rs) || force_update) &&</div>
<div style="font-family: Calibri; font-size: 11pt;">+           down_read_trylock(&adev->reset_domain->sem)) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+               mutex_lock(&virt->ras.ras_telemetry_mutex);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               ret = amdgpu_virt_req_ras_cper_dump_internal(adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               mutex_unlock(&virt->ras.ras_telemetry_mutex);</div>
<div style="font-family: Calibri; font-size: 11pt;">+               up_read(&adev->reset_domain->sem);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return ret;</div>
<div style="font-family: Calibri; font-size: 11pt;">+}</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">int amdgpu_virt_ras_telemetry_post_reset(struct amdgpu_device *adev)  {</div>
<div style="font-family: Calibri; font-size: 11pt;">         unsigned long ue_count, ce_count;</div>
<div style="font-family: Calibri; font-size: 11pt;">diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h</div>
<div style="font-family: Calibri; font-size: 11pt;">index 0f3ccae5c1ab..9f65487e60f5 100644</div>
<div style="font-family: Calibri; font-size: 11pt;">--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h</div>
<div style="font-family: Calibri; font-size: 11pt;">+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -96,6 +96,7 @@ struct amdgpu_virt_ops {</div>
<div style="font-family: Calibri; font-size: 11pt;">                                         enum amdgpu_ras_block block);</div>
<div style="font-family: Calibri; font-size: 11pt;">         bool (*rcvd_ras_intr)(struct amdgpu_device *adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">         int (*req_ras_err_count)(struct amdgpu_device *adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       int (*req_ras_cper_dump)(struct amdgpu_device *adev, u64 vf_rptr);</div>
<div style="font-family: Calibri; font-size: 11pt;">};</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">/*</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -140,6 +141,7 @@ enum AMDGIM_FEATURE_FLAG {</div>
<div style="font-family: Calibri; font-size: 11pt;">         AMDGIM_FEATURE_MES_INFO_ENABLE = (1 << 8),</div>
<div style="font-family: Calibri; font-size: 11pt;">         AMDGIM_FEATURE_RAS_CAPS = (1 << 9),</div>
<div style="font-family: Calibri; font-size: 11pt;">         AMDGIM_FEATURE_RAS_TELEMETRY = (1 << 10),</div>
<div style="font-family: Calibri; font-size: 11pt;">+       AMDGIM_FEATURE_RAS_CPER = (1 << 11),</div>
<div style="font-family: Calibri; font-size: 11pt;">};</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">enum AMDGIM_REG_ACCESS_FLAG {</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -242,6 +244,13 @@ struct amdgpu_virt_ras_err_handler_data {</div>
<div style="font-family: Calibri; font-size: 11pt;">         int last_reserved;</div>
<div style="font-family: Calibri; font-size: 11pt;">};</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+struct amdgpu_virt_ras {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct ratelimit_state ras_error_cnt_rs;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct ratelimit_state ras_cper_dump_rs;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct mutex ras_telemetry_mutex;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       uint64_t cper_rptr;</div>
<div style="font-family: Calibri; font-size: 11pt;">+};</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">/* GPU virtualization */</div>
<div style="font-family: Calibri; font-size: 11pt;">struct amdgpu_virt {</div>
<div style="font-family: Calibri; font-size: 11pt;">         uint32_t                        caps;</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -284,8 +293,7 @@ struct amdgpu_virt {</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">         union amd_sriov_ras_caps ras_en_caps;</div>
<div style="font-family: Calibri; font-size: 11pt;">         union amd_sriov_ras_caps ras_telemetry_en_caps;</div>
<div style="font-family: Calibri; font-size: 11pt;">-</div>
<div style="font-family: Calibri; font-size: 11pt;">-       struct ratelimit_state ras_telemetry_rs;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       struct amdgpu_virt_ras ras;</div>
<div style="font-family: Calibri; font-size: 11pt;">         struct amd_sriov_ras_telemetry_error_count count_cache;  };</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -340,6 +348,9 @@ struct amdgpu_video_codec_info;  #define amdgpu_sriov_ras_telemetry_block_en(adev, sriov_blk) \</div>
<div style="font-family: Calibri; font-size: 11pt;">(amdgpu_sriov_ras_telemetry_en((adev)) && (adev)->virt.ras_telemetry_en_caps.all & BIT(sriov_blk))</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+#define amdgpu_sriov_ras_cper_en(adev) \ ((adev)->virt.gim_feature &</div>
<div style="font-family: Calibri; font-size: 11pt;">+AMDGIM_FEATURE_RAS_CPER)</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">static inline bool is_virtual_machine(void)  {  #if defined(CONFIG_X86) @@ -378,7 +389,7 @@ void amdgpu_virt_release_ras_err_handler_data(struct amdgpu_device *adev);  void amdgpu_virt_init_data_exchange(struct
 amdgpu_device *adev);  void amdgpu_virt_exchange_data(struct amdgpu_device *adev);  void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev); -void amdgpu_detect_virtualization(struct amdgpu_device *adev);</div>
<div style="font-family: Calibri; font-size: 11pt;">+void amdgpu_virt_init(struct amdgpu_device *adev);</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);  int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev); @@ -406,6 +417,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev,
 u32 offset, u32 v, u32 f  bool amdgpu_virt_get_ras_capability(struct amdgpu_device *adev);  int amdgpu_virt_req_ras_err_count(struct amdgpu_device *adev, enum amdgpu_ras_block block,</div>
<div style="font-family: Calibri; font-size: 11pt;">                                   struct ras_err_data *err_data);</div>
<div style="font-family: Calibri; font-size: 11pt;">+int amdgpu_virt_req_ras_cper_dump(struct amdgpu_device *adev, bool</div>
<div style="font-family: Calibri; font-size: 11pt;">+force_update);</div>
<div style="font-family: Calibri; font-size: 11pt;">int amdgpu_virt_ras_telemetry_post_reset(struct amdgpu_device *adev);  bool amdgpu_virt_ras_telemetry_block_en(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">                                         enum amdgpu_ras_block block);</div>
<div style="font-family: Calibri; font-size: 11pt;">diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c</div>
<div style="font-family: Calibri; font-size: 11pt;">index 4dcb72d1bdda..5aadf24cb202 100644</div>
<div style="font-family: Calibri; font-size: 11pt;">--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c</div>
<div style="font-family: Calibri; font-size: 11pt;">+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -184,6 +184,9 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,</div>
<div style="font-family: Calibri; font-size: 11pt;">         case IDH_REQ_RAS_ERROR_COUNT:</div>
<div style="font-family: Calibri; font-size: 11pt;">                 event = IDH_RAS_ERROR_COUNT_READY;</div>
<div style="font-family: Calibri; font-size: 11pt;">                 break;</div>
<div style="font-family: Calibri; font-size: 11pt;">+       case IDH_REQ_RAS_CPER_DUMP:</div>
<div style="font-family: Calibri; font-size: 11pt;">+               event = IDH_RAS_CPER_DUMP_READY;</div>
<div style="font-family: Calibri; font-size: 11pt;">+               break;</div>
<div style="font-family: Calibri; font-size: 11pt;">         default:</div>
<div style="font-family: Calibri; font-size: 11pt;">                 break;</div>
<div style="font-family: Calibri; font-size: 11pt;">         }</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -467,6 +470,16 @@ static int xgpu_nv_req_ras_err_count(struct amdgpu_device *adev)</div>
<div style="font-family: Calibri; font-size: 11pt;">         return xgpu_nv_send_access_requests(adev, IDH_REQ_RAS_ERROR_COUNT);  }</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
<div style="font-family: Calibri; font-size: 11pt;">+static int xgpu_nv_req_ras_cper_dump(struct amdgpu_device *adev, u64</div>
<div style="font-family: Calibri; font-size: 11pt;">+vf_rptr) {</div>
<div style="font-family: Calibri; font-size: 11pt;">+       uint32_t vf_rptr_hi, vf_rptr_lo;</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">+       vf_rptr_hi = (uint32_t)(vf_rptr >> 32);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       vf_rptr_lo = (uint32_t)(vf_rptr & 0xFFFFFFFF);</div>
<div style="font-family: Calibri; font-size: 11pt;">+       return xgpu_nv_send_access_requests_with_param(</div>
<div style="font-family: Calibri; font-size: 11pt;">+               adev, IDH_REQ_RAS_CPER_DUMP, vf_rptr_hi, vf_rptr_lo, 0); }</div>
<div style="font-family: Calibri; font-size: 11pt;">+</div>
<div style="font-family: Calibri; font-size: 11pt;">const struct amdgpu_virt_ops xgpu_nv_virt_ops = {</div>
<div style="font-family: Calibri; font-size: 11pt;">         .req_full_gpu   = xgpu_nv_request_full_gpu_access,</div>
<div style="font-family: Calibri; font-size: 11pt;">         .rel_full_gpu   = xgpu_nv_release_full_gpu_access,</div>
<div style="font-family: Calibri; font-size: 11pt;">@@ -478,4 +491,5 @@ const struct amdgpu_virt_ops xgpu_nv_virt_ops = {</div>
<div style="font-family: Calibri; font-size: 11pt;">         .ras_poison_handler = xgpu_nv_ras_poison_handler,</div>
<div style="font-family: Calibri; font-size: 11pt;">         .rcvd_ras_intr = xgpu_nv_rcvd_ras_intr,</div>
<div style="font-family: Calibri; font-size: 11pt;">         .req_ras_err_count = xgpu_nv_req_ras_err_count,</div>
<div style="font-family: Calibri; font-size: 11pt;">+       .req_ras_cper_dump = xgpu_nv_req_ras_cper_dump,</div>
<div style="font-family: Calibri; font-size: 11pt;">};</div>
<div style="font-family: Calibri; font-size: 11pt;">--</div>
<div style="font-family: Calibri; font-size: 11pt;">2.34.1</div>
<div style="font-family: Calibri; font-size: 11pt;"> </div>
</div>
</body>
</html>