summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index a3ee6f3..4546bb0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -4111,6 +4111,8 @@ static bool svc_read_last_promote;
static u32 svc_pushdec_log;
/* r707d: bounded push-read failure witness (see svc_read_va_push_ex). */
static u32 svc_pushfail_log;
+/* r1405: bounded push-read ceiling-rejection witness (see svc_read_va_push_ex). */
+static u32 svc_pinrej_log;
/*
* SESSION 132: the util-sweep witnesses are per-CLIENT budgets (reset in
* svc_session_flush), not per-boot: on a multi-client boot the driver-init
@@ -19435,6 +19437,7 @@ static void svc_session_flush(void)
{
/* r707x: per-client witness budgets. */
svc_pushfail_log = 0;
+ svc_pinrej_log = 0;
svc_rdw_log = 0;
svc_pushdec_log = 0;
/* SESSION 132: util-sweep witnesses + their dedup keys are per-client. */
@@ -20979,6 +20982,7 @@ static int svc_read_va_push_ex(struct nv_vgpu_device *vgpu,
int ap = SVC_APERTURE_SYS;
bool have_win, done = false;
bool first = (p == buf);
+ bool rej = false; /* r1405: a source hit the PA ceiling */
int last_rc = -ENOENT;
int trusted_rc = 0;
u32 src;
@@ -21041,8 +21045,31 @@ static int svc_read_va_push_ex(struct nv_vgpu_device *vgpu,
break;
}
+ /*
+ * r1405 (S153/r1404): the strict GL carrier pins are
+ * host-verified ground truth (guest pagemap), but they
+ * live ABOVE the registered guest-RAM top (8.0-8.35 GB
+ * vs a 6 GiB boot registration), so this bound refused
+ * every pinned page with -EIO before reading it and the
+ * 60 216 B carrier read never decoded. An injected pin
+ * (src 0) is exempt: vfio_dma_rw is the hard bound, and
+ * a stale pin above the top either reads (the desired
+ * case) or fails in svc_read_ap exactly as before. The
+ * other sources keep the conservative bound, and a
+ * refused source is named by the bounded witness.
+ */
if (ap == SVC_APERTURE_SYS &&
+ !via_ipin &&
pa >= svc_push_pa_ceiling()) {
+ rej = true;
+ if (svc_pinrej_log < 96) {
+ svc_pinrej_log++;
+ pr_info("sema-pinrej: va=0x%llx pa=0x%llx src=%u ceiling=0x%llx\n",
+ (unsigned long long)va,
+ (unsigned long long)pa,
+ src,
+ (unsigned long long)svc_push_pa_ceiling());
+ }
last_rc = -EIO;
continue;
}
@@ -21273,7 +21300,7 @@ static int svc_read_va_push_ex(struct nv_vgpu_device *vgpu,
(svc_ipin_alt_lookup(va, &apa, &aap) == 0);
svc_pushfail_log++;
- pr_info("sema-pushfail: va=0x%llx chunk=0x%llx page=0x%llx last_rc=%d trusted_rc=%d ipin=%d pa=0x%llx alt=%d pa=0x%llx win=%d pa=0x%llx\n",
+ pr_info("sema-pushfail: va=0x%llx chunk=0x%llx page=0x%llx last_rc=%d trusted_rc=%d ipin=%d pa=0x%llx alt=%d pa=0x%llx win=%d pa=0x%llx ceil=0x%llx rej=%d\n",
(unsigned long long)va,
(unsigned long long)chunk,
(unsigned long long)page_va,
@@ -21282,7 +21309,9 @@ static int svc_read_va_push_ex(struct nv_vgpu_device *vgpu,
has_alt,
(unsigned long long)apa,
have_win,
- (unsigned long long)win_pa);
+ (unsigned long long)win_pa,
+ (unsigned long long)svc_push_pa_ceiling(),
+ rej);
}
return last_rc;
}
@@ -24007,6 +24036,17 @@ static void svc_gr_setup_hold_arm(struct svc_channel *ch, u64 va, u32 idx,
if (ch->gr_setup_hold_va != va || ch->gr_setup_hold_idx != idx) {
ch->gr_setup_hold_va = va;
ch->gr_setup_hold_idx = idx;
+ /*
+ * r1405 (S153/r1404): the push-read failure/reject witnesses
+ * are per setup-hold generation, not per boot. On r1404 the
+ * 96-slot budget was spent 23 s BEFORE the first strict pin
+ * landed, so no post-pin rejection row could ever print and
+ * the ceiling had to be found offline. Reset both counters on
+ * every (re-)arm so the next generation's failures are always
+ * visible; each generation is still bounded by its own cap.
+ */
+ svc_pushfail_log = 0;
+ svc_pinrej_log = 0;
if (gsp_sema_gr_setup_hold_ms)
ch->gr_setup_hold_until = jiffies +
msecs_to_jiffies(gsp_sema_gr_setup_hold_ms);