From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mm01.cs.columbia.edu (mm01.cs.columbia.edu [128.59.11.253]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FE53C433EF for ; Wed, 2 Mar 2022 21:25:41 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id 8CF0A49E2A; Wed, 2 Mar 2022 16:25:40 -0500 (EST) X-Virus-Scanned: at lists.cs.columbia.edu Authentication-Results: mm01.cs.columbia.edu (amavisd-new); dkim=softfail (fail, message has been altered) header.i=@google.com Received: from mm01.cs.columbia.edu ([127.0.0.1]) by localhost (mm01.cs.columbia.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id o2UbcgS0CS6E; Wed, 2 Mar 2022 16:25:38 -0500 (EST) Received: from mm01.cs.columbia.edu (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id 9462F410F7; Wed, 2 Mar 2022 16:25:38 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id 763A343482 for ; Wed, 2 Mar 2022 16:25:36 -0500 (EST) X-Virus-Scanned: at lists.cs.columbia.edu Received: from mm01.cs.columbia.edu ([127.0.0.1]) by localhost (mm01.cs.columbia.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4yMz5Jo5nyam for ; Wed, 2 Mar 2022 16:25:34 -0500 (EST) Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) by mm01.cs.columbia.edu (Postfix) with ESMTPS id 34580410F7 for ; Wed, 2 Mar 2022 16:25:34 -0500 (EST) Received: by mail-pl1-f170.google.com with SMTP id i1so2710784plr.2 for ; Wed, 02 Mar 2022 13:25:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=DSJKv4X7KgGu7FsUU22pIWhfKTSJUinwycebGO+swSE=; b=Z4bxuyoYzgxeSWKrJzJD6y7wbX5C5E4GHeIK8jVrI/c2ZKY/oMSQYZI/Zw24lrTRMV 2Ao22Y/Vml0vHa938pDj53pm+0zcU/P8Rwm4MqacRApwFjS7++0L/L6SbDQ9HrP7asXr PhaXe3irMhgcY95iI9u04xdIaY65dkC/Xxpa58sK52VzbuixmQCxNHORCdbvUa/Xp75k GOmyJR41dm6BNB2yPwIqcqy13kDf516xAUxEWA7FYI+xLQKHI8reKV3E4CKMM+UyQLFe BUpKqnPMKYPQp1QvTTDlvQRcYhBO6PUGhfdPrxg00F093X7IUU46tSe34g0ZthWEOS/u /AAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=DSJKv4X7KgGu7FsUU22pIWhfKTSJUinwycebGO+swSE=; b=YqbQV/fa+Nww6JxfZfrybK7Q/Ird6YXgFJZdzBQnOKmwICxSpF5UzLsakgkcEj6SSm s2FvLgZpHvSyBL1+hxwI9TG3NboHqCOi2Z1oKJm4+cBRNOC7mvmEddGjJAeYF6q1kRdp IeGYiRYyqQDYayr87rUsPT/mbRBWfw/vG3aoccD5SaQtMWV/bAxql+qEqd2nl7HrqZYM 6lL08p7Rs9673BMV+qhbcsHNbGRP33fmIl8FrEffQg56ElRx2DH2Lrp8xOb3IBnNbviP mCcYUFWqjFr42aW//O/EJgsTpB7wkOtJ6/u2qX+qrspvEDwWBivtGk1rsA4Ud43GQ0rH +MzQ== X-Gm-Message-State: AOAM532nEaAcXY7F/mZVWCHGw68muPtZ3qZRq3/sXxo41lySaPwK+Hbh bJaeEOYbcpehagzbSIktcbZC4w== X-Google-Smtp-Source: ABdhPJzooJsjmsWOCrjFPjKotLonTPkYm1cpFO1qaqpRcNgGLBSKs2YDLSRt8/7VYTEXGcrNnHgXZw== X-Received: by 2002:a17:903:124a:b0:151:99fe:1a10 with SMTP id u10-20020a170903124a00b0015199fe1a10mr4031232plh.87.1646256332860; Wed, 02 Mar 2022 13:25:32 -0800 (PST) Received: from google.com (150.12.83.34.bc.googleusercontent.com. [34.83.12.150]) by smtp.gmail.com with ESMTPSA id f13-20020a056a001acd00b004f0f9a967basm104045pfv.100.2022.03.02.13.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Mar 2022 13:25:32 -0800 (PST) Date: Wed, 2 Mar 2022 13:25:28 -0800 From: Ricardo Koller To: Oliver Upton Subject: Re: [PATCH 2/3] KVM: arm64: selftests: add arch_timer_edge_cases Message-ID: References: <20220302172144.2734258-1-ricarkol@google.com> <20220302172144.2734258-3-ricarkol@google.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Cc: kvm@vger.kernel.org, maz@kernel.org, pbonzini@redhat.com, kvmarm@lists.cs.columbia.edu X-BeenThere: kvmarm@lists.cs.columbia.edu X-Mailman-Version: 2.1.14 Precedence: list List-Id: Where KVM/ARM decisions are made List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: kvmarm-bounces@lists.cs.columbia.edu Sender: kvmarm-bounces@lists.cs.columbia.edu SGkgT2xpdmVyLAoKT24gV2VkLCBNYXIgMDIsIDIwMjIgYXQgMDg6NDU6NTNQTSArMDAwMCwgT2xp dmVyIFVwdG9uIHdyb3RlOgo+IEhpIFJpY2FyZG8sCj4gCj4gT24gV2VkLCBNYXIgMDIsIDIwMjIg YXQgMDk6MjE6NDNBTSAtMDgwMCwgUmljYXJkbyBLb2xsZXIgd3JvdGU6Cj4gPiBBZGQgYW4gYXJj aF90aW1lciBlZGdlLWNhc2VzIHNlbGZ0ZXN0LiBGb3Igbm93LCBqdXN0IGFkZCBzb21lIGJhc2lj Cj4gPiBzYW5pdHkgY2hlY2tzLCBhbmQgc29tZSBzdHJlc3MgY29uZGl0aW9ucyAobGlrZSB3YWl0 aW5nIGZvciB0aGUgdGltZXJzCj4gPiB3aGlsZSByZS1zY2hlZHVsaW5nIHRoZSB2Y3B1KS4gVGhl IG5leHQgY29tbWl0IHdpbGwgYWRkIHRoZSBhY3R1YWwgZWRnZQo+ID4gY2FzZSB0ZXN0cy4KPiA+ IAo+ID4gVGhpcyB0ZXN0IGZhaWxzIHdpdGhvdXQgYTg2N2U5ZDBjYzEgIktWTTogYXJtNjQ6IERv bid0IG1pc3MgcGVuZGluZwo+ID4gaW50ZXJydXB0cyBmb3Igc3VzcGVuZGVkIHZDUFUiLgo+ID4g Cj4gCj4gVGVzdGluZyB0aW1lciBjb3JyZWN0bmVzcyBpcyBleHRyZW1lbHkgY2hhbGxlbmdpbmcg dG8gZG8gd2l0aG91dAo+IGluaGVyZW50IGZsYWtpbmVzcy4gSSBoYXZlIHNvbWUgY29uY2VybnMg YWJvdXQgdGhlIGV4cGVjdGF0aW9ucyB0aGF0IGEKPiB0aW1lciBJUlEgc2hvdWxkIGZpcmUgaW4g YSBnaXZlbiBhbW91bnQgb2YgdGltZSwgYXMgaXQgaXMgcG9zc2libGUgdG8KPiBmbGFrZSBmb3Ig YW55IG51bWJlciBvZiBiZW5pZ24gcmVhc29ucyAoc3VjaCBhcyBoaWdoIENQVSBsb2FkIGluIHRo ZQo+IGhvc3QpLgo+IAo+IFdoaWxlIHRoZSBhcmNoaXRlY3R1cmUgbWF5IHN1Z2dlc3QgdGhhdCB0 aGUgdGltZXIgc2hvdWxkIGZpcmUgYXMgc29vbiBhcwo+IENWQUwgaXMgbWV0Ogo+IAo+ICAgVGlt ZXJDb25kaXRpb25NZXQgPSAoKChDb3VudGVyWzYzOjBdIOKAkyBPZmZzZXRbNjM6MF0pWzYzOjBd IC0gQ29tcGFyZVZhbHVlWzYzOjBdKSA+PSAwKQo+IAo+IEhvd2V2ZXIsIHRoZSBhcmNoaXRlY3R1 cmUgaXMgZXh0cmVtZWx5IGltcHJlY2lzZSBhcyB0byB3aGVuIGFuIGludGVycnVwdAo+IHNob3Vs ZCBiZSB0YWtlbjoKPiAKPiAgIEluIHRoZSBhYnNlbmNlIG9mIGEgc3BlY2lmaWMgcmVxdWlyZW1l bnQgdG8gdGFrZSBhbiBpbnRlcnJ1cHQsIHRoZQo+ICAgYXJjaGl0ZWN0dXJlIG9ubHkgcmVxdWly ZXMgdGhhdCB1bm1hc2tlZCBwZW5kaW5nIGludGVycnVwdHMgYXJlIHRha2VuCj4gICBpbiBmaW5p dGUgdGltZS4gW0RESTA0ODdHLmIgRDEuMTMuNCAiUHJpb3JpdGl6YXRpb24gYW5kIHJlY29nbml0 aW9uIG9mCj4gICBpbnRlcnJ1cHRzIl0KPiAKPiBJdCBzZWVtcyB0byBtZSB0aGF0IHRoZSBvbmx5 IHRoaW5nIHdlIGNhbiBwb3NpdGl2ZWx5IGFzc2VydCBpcyB0aGF0IGEKPiB0aW1lciBpbnRlcnJ1 cHQgc2hvdWxkIG5ldmVyIGJlIHRha2VuIGVhcmx5LiBOb3cgLS0gSSBhZ3JlZSB0aGF0IHRoZXJl Cj4gaXMgdmFsdWUgaW4gdGVzdGluZyB0aGF0IHRoZSBpbnRlcnJ1cHQgYmUgdGFrZW4gaW4gYm91 bmRlZCB0aW1lLCBidXQgaXRzCj4gaGFyZCB0byBwaWNrIGEgZ29vZCB2YWx1ZSBmb3IgaXQuCgpZ ZXMsIGEgdGltZXIgdGhhdCBuZXZlciBmaXJlcyBwYXNzZXMgdGhlIHRlc3QsIGJ1dCBpdCdzIG5v dCB2ZXJ5IHVzZWZ1bC4KCkkgc2F3IGRlbGF5IGlzc3VlcyBpbW1lZGlhdGVseSBhZnRlciB0ZXN0 aW5nIHdpdGggUUVNVS4gSSd2ZSBiZWVuIHBsYXllZAp3aXRoIHZhbHVlcyBhbmQgZm91bmQgdGhh dCAxbXMgaXMgZW5vdWdoIGZvciBhbGwgb2YgbXkgcnVucyAoUUVNVQppbmNsdWRlZCkgdG8gcGFz cyAoMTAwMDAgaXRlcmF0aW9ucyBjb25jdXJyZW50bHkgb24gYWxsIG15IDY0IGNwdXMpLiBJCmp1 c3QgY2hlY2tlZCBpbiB0aGUgZmFzdCBtb2RlbCBhbmQgMW1zIHNlZW1zIHRvIGJlIGVub3VnaCBh cyB3ZWxsCihhbHRob3VnaCBJIGRpZG4ndCBjaGVjayBmb3Igc28gbG9uZykuCgoJLyogMW1zIHNv dW5kcyBhIGJpdCBleGNlc3NpdmUsIGJ1dCBRRU1VLVRDRyBpcyBzbG93LiAqLwoJI2RlZmluZSBU RVNUX01BUkdJTl9VUwkJCTEwMDBVTEwKCj4gCj4gUGVyaGFwcyBkb2N1bWVudGluZyB0aGUgcG9z c2liaWxpdHkgb2YgZmxha2VzIGluIHRoZSB0ZXN0IGlzIHdhcnJhbnRlZCwKPiBhbG9uZyB3aXRo IHNvbWUga25vYnMgdG8gYWRqdXN0IHRoZXNlIHZhbHVlcyBmb3IgYW55IHBhcnRpY3VsYXJseSBi YWQKPiBpbXBsZW1lbnRhdGlvbi4KCldoYXQgYWJvdXQgaGF2aW5nIGEgY21kbGluZSBhcmcgdG8g ZW5hYmxlIHRob3NlIHRlc3RzPwoKPiAKPiA+IFJldmlld2VkLWJ5OiBSZWlqaSBXYXRhbmFiZSA8 cmVpaml3QGdvb2dsZS5jb20+Cj4gPiBSZXZpZXdlZC1ieTogUmFnaGF2ZW5kcmEgUmFvIEFuYW50 YSA8cmFuYW50YUBnb29nbGUuY29tPgo+ID4gU2lnbmVkLW9mZi1ieTogUmljYXJkbyBLb2xsZXIg PHJpY2Fya29sQGdvb2dsZS5jb20+Cj4gPiAtLS0KPiA+ICB0b29scy90ZXN0aW5nL3NlbGZ0ZXN0 cy9rdm0vLmdpdGlnbm9yZSAgICAgICAgfCAgIDEgKwo+ID4gIHRvb2xzL3Rlc3Rpbmcvc2VsZnRl c3RzL2t2bS9NYWtlZmlsZSAgICAgICAgICB8ICAgMSArCj4gPiAgLi4uL2t2bS9hYXJjaDY0L2Fy Y2hfdGltZXJfZWRnZV9jYXNlcy5jICAgICAgIHwgNjM0ICsrKysrKysrKysrKysrKysrKwo+ID4g IDMgZmlsZXMgY2hhbmdlZCwgNjM2IGluc2VydGlvbnMoKykKPiA+ICBjcmVhdGUgbW9kZSAxMDA2 NDQgdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtL2FhcmNoNjQvYXJjaF90aW1lcl9lZGdlX2Nh c2VzLmMKPiA+IAo+ID4gZGlmZiAtLWdpdCBhL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2t2bS8u Z2l0aWdub3JlIGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtLy5naXRpZ25vcmUKPiA+IGlu ZGV4IGRjZTdkZTc3NTVlNi4uOGY3ZTAxMjNkZDI4IDEwMDY0NAo+ID4gLS0tIGEvdG9vbHMvdGVz dGluZy9zZWxmdGVzdHMva3ZtLy5naXRpZ25vcmUKPiA+ICsrKyBiL3Rvb2xzL3Rlc3Rpbmcvc2Vs ZnRlc3RzL2t2bS8uZ2l0aWdub3JlCj4gPiBAQCAtMSw1ICsxLDYgQEAKPiA+ICAjIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPiA+ICAvYWFyY2g2NC9hcmNoX3RpbWVyCj4g PiArL2FhcmNoNjQvYXJjaF90aW1lcl9lZGdlX2Nhc2VzCj4gPiAgL2FhcmNoNjQvZGVidWctZXhj ZXB0aW9ucwo+ID4gIC9hYXJjaDY0L2dldC1yZWctbGlzdAo+ID4gIC9hYXJjaDY0L3BzY2lfY3B1 X29uX3Rlc3QKPiA+IGRpZmYgLS1naXQgYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9rdm0vTWFr ZWZpbGUgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9rdm0vTWFrZWZpbGUKPiA+IGluZGV4IDBl NDkyNmJjOWE1OC4uMTdhMGYzMmNmYzkxIDEwMDY0NAo+ID4gLS0tIGEvdG9vbHMvdGVzdGluZy9z ZWxmdGVzdHMva3ZtL01ha2VmaWxlCj4gPiArKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9r dm0vTWFrZWZpbGUKPiA+IEBAIC0xMDEsNiArMTAxLDcgQEAgVEVTVF9HRU5fUFJPR1NfeDg2XzY0 ICs9IGt2bV9iaW5hcnlfc3RhdHNfdGVzdAo+ID4gIFRFU1RfR0VOX1BST0dTX3g4Nl82NCArPSBz eXN0ZW1fY291bnRlcl9vZmZzZXRfdGVzdAo+ID4gIAo+ID4gIFRFU1RfR0VOX1BST0dTX2FhcmNo NjQgKz0gYWFyY2g2NC9hcmNoX3RpbWVyCj4gPiArVEVTVF9HRU5fUFJPR1NfYWFyY2g2NCArPSBh YXJjaDY0L2FyY2hfdGltZXJfZWRnZV9jYXNlcwo+ID4gIFRFU1RfR0VOX1BST0dTX2FhcmNoNjQg Kz0gYWFyY2g2NC9kZWJ1Zy1leGNlcHRpb25zCj4gPiAgVEVTVF9HRU5fUFJPR1NfYWFyY2g2NCAr PSBhYXJjaDY0L2dldC1yZWctbGlzdAo+ID4gIFRFU1RfR0VOX1BST0dTX2FhcmNoNjQgKz0gYWFy Y2g2NC9wc2NpX2NwdV9vbl90ZXN0Cj4gPiBkaWZmIC0tZ2l0IGEvdG9vbHMvdGVzdGluZy9zZWxm dGVzdHMva3ZtL2FhcmNoNjQvYXJjaF90aW1lcl9lZGdlX2Nhc2VzLmMgYi90b29scy90ZXN0aW5n L3NlbGZ0ZXN0cy9rdm0vYWFyY2g2NC9hcmNoX3RpbWVyX2VkZ2VfY2FzZXMuYwo+ID4gbmV3IGZp bGUgbW9kZSAxMDA2NDQKPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4uNDhjODg2YmNlODQ5Cj4gPiAt LS0gL2Rldi9udWxsCj4gPiArKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9rdm0vYWFyY2g2 NC9hcmNoX3RpbWVyX2VkZ2VfY2FzZXMuYwo+ID4gQEAgLTAsMCArMSw2MzQgQEAKPiA+ICsvLyBT UERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5Cj4gPiArLyoKPiA+ICsgKiBhcmNo X3RpbWVyX2VkZ2VfY2FzZXMuYyAtIFRlc3RzIHRoZSBhYXJjaDY0IHRpbWVyIElSUSBmdW5jdGlv bmFsaXR5Lgo+ID4gKyAqCj4gPiArICogQ29weXJpZ2h0IChjKSAyMDIxLCBHb29nbGUgTExDLgo+ ID4gKyAqLwo+ID4gKwo+ID4gKyNkZWZpbmUgX0dOVV9TT1VSQ0UKPiA+ICsKPiA+ICsjaW5jbHVk ZSA8c3RkbGliLmg+Cj4gPiArI2luY2x1ZGUgPHB0aHJlYWQuaD4KPiA+ICsjaW5jbHVkZSA8bGlu dXgva3ZtLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3NpemVzLmg+Cj4gPiArI2luY2x1ZGUgPGxp bnV4L2JpdG1hcC5oPgo+ID4gKyNpbmNsdWRlIDxzY2hlZC5oPgo+ID4gKyNpbmNsdWRlIDxzeXMv c3lzaW5mby5oPgo+ID4gKwo+ID4gKyNpbmNsdWRlICJrdm1fdXRpbC5oIgo+ID4gKyNpbmNsdWRl ICJwcm9jZXNzb3IuaCIKPiA+ICsjaW5jbHVkZSAiZGVsYXkuaCIKPiA+ICsjaW5jbHVkZSAiYXJj aF90aW1lci5oIgo+ID4gKyNpbmNsdWRlICJnaWMuaCIKPiA+ICsjaW5jbHVkZSAidmdpYy5oIgo+ ID4gKwo+ID4gKyNkZWZpbmUgVkNQVUlECQkJCTAKPiA+ICsKPiA+ICsjZGVmaW5lIG1zZWNzX3Rv X3VzZWNzKG1zZWMpCQkoKG1zZWMpICogMTAwMExMKQo+ID4gKwo+ID4gKyNkZWZpbmUgQ1ZBTF9N QVgJCQl+MFVMTAo+ID4gKy8qIHR2YWwgaXMgYSBzaWduZWQgMzItYml0IGludC4gKi8KPiA+ICsj ZGVmaW5lIFRWQUxfTUFYCQkJSU5UX01BWAo+ID4gKyNkZWZpbmUgVFZBTF9NSU4JCQlJTlRfTUlO Cj4gPiArCj4gPiArI2RlZmluZSBHSUNEX0JBU0VfR1BBCQkJMHg4MDAwMDAwVUxMCj4gPiArI2Rl ZmluZSBHSUNSX0JBU0VfR1BBCQkJMHg4MEEwMDAwVUxMCj4gPiArCj4gPiArLyogQWZ0ZXIgaG93 IG11Y2ggdGltZSB3ZSBzYXkgdGhlcmUgaXMgbm8gSVJRLiAqLwo+ID4gKyNkZWZpbmUgVElNRU9V VF9OT19JUlFfVVMJCW1zZWNzX3RvX3VzZWNzKDUwKQo+ID4gKwo+ID4gKy8qIDFtcyBzb3VuZHMg YSBiaXQgZXhjZXNzaXZlLCBidXQgUUVNVS1UQ0cgaXMgc2xvdy4gKi8KPiA+ICsjZGVmaW5lIFRF U1RfTUFSR0lOX1VTCQkJMTAwMFVMTAo+ID4gKwo+ID4gKy8qIEEgbmljZSBjb3VudGVyIHZhbHVl IHRvIHVzZSBhcyB0aGUgc3RhcnRpbmcgb25lIGZvciBtb3N0IHRlc3RzLiAqLwo+ID4gKyNkZWZp bmUgREVGX0NOVAkJCQkoQ1ZBTF9NQVggLyAyKQo+ID4gKwo+ID4gKy8qIE51bWJlciBvZiBydW5z LiAqLwo+ID4gKyNkZWZpbmUgTlJfVEVTVF9JVEVSU19ERUYJCTUKPiA+ICsKPiA+ICsvKiBTaGFy ZWQgd2l0aCBJUlEgaGFuZGxlci4gKi8KPiA+ICt2b2xhdGlsZSBzdHJ1Y3QgdGVzdF92Y3B1X3No YXJlZF9kYXRhIHsKPiA+ICsJaW50IGhhbmRsZWQ7Cj4gPiArfSBzaGFyZWRfZGF0YTsKPiA+ICsK PiA+ICtzdHJ1Y3QgdGVzdF9hcmdzIHsKPiA+ICsJLyogVmlydHVhbCBvciBwaHlzaWNhbCB0aW1l ciBhbmQgY291bnRlciB0ZXN0cy4gKi8KPiA+ICsJZW51bSBhcmNoX3RpbWVyIHRpbWVyOwo+ID4g KwkvKiBOdW1iZXIgb2YgaXRlcmF0aW9ucy4gKi8KPiA+ICsJaW50IGl0ZXJhdGlvbnM7Cj4gPiAr fTsKPiA+ICsKPiA+ICtzdHJ1Y3QgdGVzdF9hcmdzIHRlc3RfYXJncyA9IHsKPiA+ICsJLyogT25s eSB0ZXN0aW5nIFZJUlRVQUwgdGltZXJzIGZvciBub3cuICovCj4gPiArCS50aW1lciA9IFZJUlRV QUwsCj4gPiArCS5pdGVyYXRpb25zID0gTlJfVEVTVF9JVEVSU19ERUYsCj4gPiArfTsKPiA+ICsK PiA+ICtzdGF0aWMgaW50IHZ0aW1lcl9pcnEsIHB0aW1lcl9pcnE7Cj4gPiArCj4gPiArdHlwZWRl ZiBlbnVtIHN5bmNfY21kIHsKPiA+ICsJU0VUX1JFR19LVk1fUkVHX0FSTV9USU1FUl9DTlQgPSAx MDAwMDEsCj4gPiArCVVTRVJTUEFDRV9TQ0hFRF9ZSUVMRCwKPiA+ICsJVVNFUlNQQUNFX01JR1JB VEVfU0VMRiwKPiA+ICt9IHN5bmNfY21kX3Q7Cj4gPiArCj4gPiArdHlwZWRlZiB2b2lkICgqd2Zp X21ldGhvZF90KSh2b2lkKTsKPiA+ICsKPiAKPiBuaXQ6IHRoZSBuYW1lIHN1Z2dlc3RzIHRvIG1l IGEgV0ZJIGluIHRoZSBhcmNoaXRlY3R1cmFsIHNlbnNlLCBidXQgaXQKPiBhcHBlYXJzIHBvbGxp bmcgaXMgZW1wbG95ZWQgaW4gY2VydGFpbiBpbXBsZW1lbnRhdGlvbnMuIFBlcmhhcHMgY2FsbCBp dAo+IHdhaXRfbWV0aG9kX3Q/Cj4gCj4gPiArc3RhdGljIHZvaWQgd2FpdF9mb3Jfbm9uX3NwdXJp b3VzX2lycSh2b2lkKTsKPiA+ICtzdGF0aWMgdm9pZCB3YWl0X3BvbGxfZm9yX2lycSh2b2lkKTsK PiA+ICtzdGF0aWMgdm9pZCB3YWl0X3NjaGVkX3BvbGxfZm9yX2lycSh2b2lkKTsKPiA+ICtzdGF0 aWMgdm9pZCB3YWl0X21pZ3JhdGVfcG9sbF9mb3JfaXJxKHZvaWQpOwo+ID4gKwo+ID4gK3dmaV9t ZXRob2RfdCB3ZmlfbWV0aG9kW10gPSB7Cj4gPiArCXdhaXRfZm9yX25vbl9zcHVyaW91c19pcnEs Cj4gPiArCXdhaXRfcG9sbF9mb3JfaXJxLAo+ID4gKwl3YWl0X3NjaGVkX3BvbGxfZm9yX2lycSwK PiA+ICsJd2FpdF9taWdyYXRlX3BvbGxfZm9yX2lycSwKPiA+ICt9Owo+ID4gKwo+ID4gKyNkZWZp bmUgZm9yX2VhY2hfd2ZpX21ldGhvZChpKQkJCQkJCQlcCj4gPiArCWZvciAoKGkpID0gMDsgKGkp IDwgQVJSQVlfU0laRSh3ZmlfbWV0aG9kKTsgKGkpKyspCj4gCj4gbml0OiBmb3Igc2ltcGxlIGl0 ZXJhdG9ycyBzdWNoIGFzIHRoaXMsIEkgd291bGQgcHJlZmVyIGl0IGJlIG9wZW4tY29kZWQKPiBp bnN0ZWFkIG9mIGRlZmluZWQgaW4gYSBtYWNyby4KPiAKPiA+ICt0eXBlZGVmIGVudW0gdGltZXJf dmlldyB7Cj4gPiArCVRJTUVSX0NWQUwgPSAxLAo+IAo+IG5pdDogZG8gd2UgY2FyZSBhYm91dCB0 aGUgZW51bWVyYXRpb24gdmFsdWU/IFNhbWUgZ29lcyBmb3IgZW51bQo+IHN5bmNfY21kLgo+IAo+ ID4gKwlUSU1FUl9UVkFMLAo+ID4gK30gdGltZXJfdmlld190Owo+IAo+IG5pdDogZHJvcCB0aGUg dHlwZWRlZiBhbmQganVzdCByZWZlciB0byB0aGUgZW51bSB0eXBlIGV4cGxpY2l0bHkuIEknZAo+ IHJlY29tbWVuZCB0aGlzIGZvciBvdGhlciBlbnVtcyBpbiB0aGlzIHRlc3QgYXMgd2VsbC4KPiAK PiA+ICsKPiA+ICsvKiBQYWlyIG9mIHBjcHVzIGZvciB0aGUgdGVzdCB0byBhbHRlcm5hdGUgYmV0 d2Vlbi4gKi8KPiA+ICtzdGF0aWMgaW50IHBjcHVzWzJdID0gey0xLCAtMX07Cj4gPiArc3RhdGlj IGludCBwY3B1c19pZHg7Cj4gPiArCj4gPiArc3RhdGljIHVpbnQzMl90IG5leHRfcGNwdSh2b2lk KQo+ID4gK3sKPiA+ICsJcGNwdXNfaWR4ID0gMSAtIHBjcHVzX2lkeDsKPiA+ICsJcmV0dXJuIHBj cHVzW3BjcHVzX2lkeF07Cj4gPiArfQo+ID4gKwo+ID4gKyNkZWZpbmUgQVNTRVJUX0lSUVNfSEFO RExFRF8yKF9fbnIsIGFyZzEsIGFyZzIpIGRvIHsJCQkJXAo+ID4gKwlpbnQgX19oID0gc2hhcmVk X2RhdGEuaGFuZGxlZDsJCQkJCQlcCj4gPiArCUdVRVNUX0FTU0VSVF80KF9faCA9PSAoX19uciks IF9faCwgX19uciwgYXJnMSwgYXJnMik7CQkJXAo+ID4gK30gd2hpbGUgKDApCj4gPiArCj4gPiAr I2RlZmluZSBBU1NFUlRfSVJRU19IQU5ETEVEXzEoX19uciwgYXJnMSkJCQkJCVwKPiA+ICsJQVNT RVJUX0lSUVNfSEFORExFRF8yKChfX25yKSwgYXJnMSwgMCkKPiA+ICsKPiA+ICsjZGVmaW5lIEFT U0VSVF9JUlFTX0hBTkRMRUQoX19ucikJCQkJCQlcCj4gPiArCUFTU0VSVF9JUlFTX0hBTkRMRURf MigoX19uciksIDAsIDApCj4gPiArCj4gPiArI2RlZmluZSBUSU1FUl9HRVRfQ1RMKCkJCQkJCQkJ CVwKPiA+ICsJdGltZXJfZ2V0X2N0bCh0ZXN0X2FyZ3MudGltZXIpCj4gPiArCj4gPiArI2RlZmlu ZSBUSU1FUl9TRVRfQ1RMKF9fY3RsKQkJCQkJCQlcCj4gPiArCXRpbWVyX3NldF9jdGwodGVzdF9h cmdzLnRpbWVyLCAoX19jdGwpKQo+ID4gKwo+ID4gKyNkZWZpbmUgVElNRVJfU0VUX0NWQUwoX19j dmFsKQkJCQkJCQlcCj4gPiArCXRpbWVyX3NldF9jdmFsKHRlc3RfYXJncy50aW1lciwgKF9fY3Zh bCkpCj4gPiArCj4gPiArI2RlZmluZSBUSU1FUl9TRVRfVFZBTChfX3R2YWwpCQkJCQkJCVwKPiA+ ICsJdGltZXJfc2V0X3R2YWwodGVzdF9hcmdzLnRpbWVyLCAoX190dmFsKSkKPiA+ICsKPiA+ICsj ZGVmaW5lIFRJTUVSX0dFVF9DVkFMKCkJCQkJCQkJXAo+ID4gKwl0aW1lcl9nZXRfY3ZhbCh0ZXN0 X2FyZ3MudGltZXIpCj4gPiArCj4gPiArI2RlZmluZSBUSU1FUl9HRVRfVFZBTCgpCQkJCQkJCVwK PiA+ICsJdGltZXJfZ2V0X3R2YWwodGVzdF9hcmdzLnRpbWVyKQo+ID4gKwo+ID4gKyNkZWZpbmUg VElNRVJfR0VUX0NOVENUKCkJCQkJCQkJXAo+ID4gKwl0aW1lcl9nZXRfY250Y3QodGVzdF9hcmdz LnRpbWVyKQo+IAo+IEl0IG1pZ2h0IGJlIGNsZWFuZXIgdG8gYXZvaWQgdGhlc2UgbWFjcm8gaW5k aXJlY3Rpb25zIGFuZCBqdXN0IGhhdmUgdGhlCj4gY2FsbGVyIHBhc3MgdGVzdF9hcmdzLnRpbWVy IG9uIGl0cyBvd24uIENvdWxkIHVzZSBhIGxvY2FsIHZhcmlhYmxlIGluCj4gdGhlIGNhbGxlciBi b2R5IHRvIGF2b2lkIHJlZmVyZW5jaW5nIHRoZSBzdHJ1Y3QgZXZlcnkgdGltZS4KPiAKPiA+ICsj ZGVmaW5lIF9fU0VUX0NPVU5URVIoX19jdHIsIF9fdCkJCQkJCQlcCj4gPiArCUdVRVNUX1NZTkNf QVJHUyhTRVRfUkVHX0tWTV9SRUdfQVJNX1RJTUVSX0NOVCwgKF9fY3RyKSwgKF9fdCksIDAsIDAp Cj4gPiArCj4gPiArI2RlZmluZSBTRVRfQ09VTlRFUihfX2N0cikJCQkJCQkJXAo+ID4gKwlfX1NF VF9DT1VOVEVSKChfX2N0ciksIHRlc3RfYXJncy50aW1lcikKPiA+ICsKPiA+ICsjZGVmaW5lIFVT RVJTUEFDRV9DTUQoX19jbWQpCQkJCQkJCVwKPiA+ICsJR1VFU1RfU1lOQ19BUkdTKF9fY21kLCAw LCAwLCAwLCAwKQo+ID4gKwo+ID4gKyNkZWZpbmUgVVNFUlNQQUNFX1NDSEVEVUxFKCkJCQkJCQkJ XAo+ID4gKwlVU0VSU1BBQ0VfQ01EKFVTRVJTUEFDRV9TQ0hFRF9ZSUVMRCkKPiA+ICsKPiA+ICsj ZGVmaW5lIFVTRVJTUEFDRV9NSUdSQVRFX1ZDUFUoKQkJCQkJCVwKPiA+ICsJVVNFUlNQQUNFX0NN RChVU0VSU1BBQ0VfTUlHUkFURV9TRUxGKQo+ID4gKwo+ID4gKyNkZWZpbmUgSUFSX1NQVVJJT1VT CQkxMDIzCj4gPiArCj4gCj4gaG93IGFib3V0IElOVElEX1NQVVJJT1VTPyBBbHNvLCB0aGlzIGlz IGFuIGludmFyaWFudCBpbiB0aGUgR0lDCj4gYXJjaGl0ZWN0dXJlLCBzbyBtYXliZSBob2lzdCBp dCBpbnRvIHRoZSBzZWxmdGVzdHMgR0lDIGhlYWRlcnMuCj4gCj4gPiArc3RhdGljIHZvaWQgZ3Vl c3RfaXJxX2hhbmRsZXIoc3RydWN0IGV4X3JlZ3MgKnJlZ3MpCj4gPiArewo+ID4gKwl1bnNpZ25l ZCBpbnQgaW50aWQgPSBnaWNfZ2V0X2FuZF9hY2tfaXJxKCk7Cj4gPiArCXVpbnQ2NF90IGNudCwg Y3ZhbDsKPiA+ICsJdWludDMyX3QgY3RsOwo+ID4gKwo+ID4gKwlHVUVTVF9BU1NFUlQoZ2ljX2ly cV9nZXRfcGVuZGluZyhpbnRpZCkpOwo+ID4gKwo+ID4gKwlpZiAoaW50aWQgPT0gSUFSX1NQVVJJ T1VTKQo+ID4gKwkJcmV0dXJuOwo+ID4gKwo+ID4gKwljdGwgPSBUSU1FUl9HRVRfQ1RMKCk7Cj4g PiArCWNudCA9IFRJTUVSX0dFVF9DTlRDVCgpOwo+ID4gKwljdmFsID0gVElNRVJfR0VUX0NWQUwo KTsKPiA+ICsKPiA+ICsJR1VFU1RfQVNTRVJUXzEoY3RsICYgQ1RMX0lTVEFUVVMsIGN0bCk7Cj4g PiArCj4gPiArCS8qIERpc2FibGUgYW5kIG1hc2sgdGhlIHRpbWVyLiAqLwo+ID4gKwlUSU1FUl9T RVRfQ1RMKENUTF9JTUFTSyk7Cj4gPiArCUdVRVNUX0FTU0VSVCghZ2ljX2lycV9nZXRfcGVuZGlu ZyhpbnRpZCkpOwo+ID4gKwo+ID4gKwlzaGFyZWRfZGF0YS5oYW5kbGVkKys7Cj4gPiArCj4gPiAr CUdVRVNUX0FTU0VSVF8yKGNudCA+PSBjdmFsLCBjbnQsIGN2YWwpOwo+ID4gKwo+ID4gKwlnaWNf c2V0X2VvaShpbnRpZCk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lkIHNldF9jdmFsX2ly cSh1aW50NjRfdCBjdmFsX2N5Y2xlcywgdWludDMyX3QgY3RsKQo+ID4gK3sKPiA+ICsJc2hhcmVk X2RhdGEuaGFuZGxlZCA9IDA7Cj4gPiArCVRJTUVSX1NFVF9DVkFMKGN2YWxfY3ljbGVzKTsKPiA+ ICsJVElNRVJfU0VUX0NUTChjdGwpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCBzZXRf dHZhbF9pcnEodWludDY0X3QgdHZhbF9jeWNsZXMsIHVpbnQzMl90IGN0bCkKPiA+ICt7Cj4gPiAr CXNoYXJlZF9kYXRhLmhhbmRsZWQgPSAwOwo+ID4gKwlUSU1FUl9TRVRfVFZBTCh0dmFsX2N5Y2xl cyk7Cj4gPiArCVRJTUVSX1NFVF9DVEwoY3RsKTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZv aWQgc2V0X3h2YWxfaXJxKHVpbnQ2NF90IHh2YWwsIHVpbnQzMl90IGN0bCwgdGltZXJfdmlld190 IHR2KQo+IAo+IG5pdDogaG93IGFib3V0IHByb2dyYW1fdGltZXJfaXJxKCkuCj4gCj4gPiArewo+ ID4gKwlzd2l0Y2ggKHR2KSB7Cj4gPiArCWNhc2UgVElNRVJfQ1ZBTDoKPiA+ICsJCXNldF9jdmFs X2lycSh4dmFsLCBjdGwpOwo+IAo+IG5pdDoganVzdCBpbmxpbmUgdGhlc2UgaGVscGVycyBpbnRv IHRoZSBzd2l0Y2ggc3RhdGVtZW50IGJvZHkuCj4gCj4gPiArCQlicmVhazsKPiA+ICsJY2FzZSBU SU1FUl9UVkFMOgo+ID4gKwkJc2V0X3R2YWxfaXJxKHh2YWwsIGN0bCk7Cj4gPiArCQlicmVhazsK PiA+ICsJZGVmYXVsdDoKPiA+ICsJCUdVRVNUX0FTU0VSVCgwKTsKPiA+ICsJfQo+ID4gK30KPiA+ ICsKPiA+ICsvKgo+ID4gKyAqIFNob3VsZCBiZSBjYWxsZWQgd2l0aCBJUlFzIG1hc2tlZC4KPiA+ ICsgKgo+ID4gKyAqIE5vdGUgdGhhdCB0aGlzIGNhbiBoYW5nIGZvcmV2ZXIsIHNvIHdlIHJlbHkg b24gaGF2aW5nIGEgdGltZW91dCBtZWNoYW5pc20gaW4KPiA+ICsgKiB0aGUgInJ1bm5lciIsIGxp a2U6IHRvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2tzZWxmdGVzdC9ydW5uZXIuc2guCj4gPiArICov Cj4gPiArc3RhdGljIHZvaWQgd2FpdF9mb3Jfbm9uX3NwdXJpb3VzX2lycSh2b2lkKQo+ID4gK3sK PiA+ICsJaW50IGg7Cj4gPiArCj4gPiArCWZvciAoaCA9IHNoYXJlZF9kYXRhLmhhbmRsZWQ7IGgg PT0gc2hhcmVkX2RhdGEuaGFuZGxlZDspIHsKPiA+ICsJCWFzbSB2b2xhdGlsZSgid2ZpXG4iCj4g PiArCQkJICAgICAibXNyIGRhaWZjbHIsICMyXG4iCj4gPiArCQkJICAgICAvKiBoYW5kbGUgSVJR ICovCj4gPiArCQkJICAgICAibXNyIGRhaWZzZXQsICMyXG4iCj4gPiArCQkJICAgICA6IDogOiAi bWVtb3J5Iik7Cj4gPiArCX0KPiA+ICt9Cj4gPiArCj4gPiArLyoKPiA+ICsgKiBXYWl0IGZvciBh biBub24tc3B1cmlvdXMgSVJRIGJ5IHBvbGxpbmcgaW4gdGhlIGd1ZXN0ICh1c2Vyc3BhY2U9MCkg b3IgaW4KPiA+ICsgKiB1c2Vyc3BhY2UgKGUuZy4sIHVzZXJzcGFjZT0xIGFuZCB1c2Vyc3BhY2Vf Y21kPVVTRVJTUEFDRV9TQ0hFRF9ZSUVMRCkuCj4gPiArICoKPiA+ICsgKiBTaG91bGQgYmUgY2Fs bGVkIHdpdGggSVJRcyBtYXNrZWQuIE5vdCByZWFsbHkgbmVlZGVkIGxpa2UgdGhlIHdmaSBhYm92 ZSwgYnV0Cj4gPiArICogaXQgc2hvdWxkIG1hdGNoIHRoZSBvdGhlcnMuCj4gPiArICoKPiA+ICsg KiBOb3RlIHRoYXQgdGhpcyBjYW4gaGFuZyBmb3JldmVyLCBzbyB3ZSByZWx5IG9uIGhhdmluZyBh IHRpbWVvdXQgbWVjaGFuaXNtIGluCj4gPiArICogdGhlICJydW5uZXIiLCBsaWtlOiB0b29scy90 ZXN0aW5nL3NlbGZ0ZXN0cy9rc2VsZnRlc3QvcnVubmVyLnNoLgo+ID4gKyAqLwo+ID4gK3N0YXRp YyB2b2lkIHBvbGxfZm9yX25vbl9zcHVyaW91c19pcnEoYm9vbCB1c2Vyc3BhY2UsIHN5bmNfY21k X3QgdXNlcnNwYWNlX2NtZCkKPiA+ICt7Cj4gPiArCWludCBoOwo+ID4gKwo+ID4gKwloID0gc2hh cmVkX2RhdGEuaGFuZGxlZDsKPiA+ICsKPiA+ICsJbG9jYWxfaXJxX2VuYWJsZSgpOwo+ID4gKwl3 aGlsZSAoaCA9PSBzaGFyZWRfZGF0YS5oYW5kbGVkKSB7Cj4gPiArCQlpZiAodXNlcnNwYWNlKQo+ ID4gKwkJCVVTRVJTUEFDRV9DTUQodXNlcnNwYWNlX2NtZCk7Cj4gPiArCQllbHNlCj4gPiArCQkJ Y3B1X3JlbGF4KCk7Cj4gPiArCX0KPiA+ICsJbG9jYWxfaXJxX2Rpc2FibGUoKTsKPiA+ICt9Cj4g PiArCj4gPiArc3RhdGljIHZvaWQgd2FpdF9wb2xsX2Zvcl9pcnEodm9pZCkKPiA+ICt7Cj4gPiAr CXBvbGxfZm9yX25vbl9zcHVyaW91c19pcnEoZmFsc2UsIC0xKTsKPiA+ICt9Cj4gPiArCj4gPiAr c3RhdGljIHZvaWQgd2FpdF9zY2hlZF9wb2xsX2Zvcl9pcnEodm9pZCkKPiA+ICt7Cj4gPiArCXBv bGxfZm9yX25vbl9zcHVyaW91c19pcnEodHJ1ZSwgVVNFUlNQQUNFX1NDSEVEX1lJRUxEKTsKPiA+ ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgd2FpdF9taWdyYXRlX3BvbGxfZm9yX2lycSh2b2lk KQo+ID4gK3sKPiA+ICsJcG9sbF9mb3Jfbm9uX3NwdXJpb3VzX2lycSh0cnVlLCBVU0VSU1BBQ0Vf TUlHUkFURV9TRUxGKTsKPiA+ICt9Cj4gPiArCj4gPiArLyoKPiA+ICsgKiBSZXNldCB0aGUgdGlt ZXIgc3RhdGUgdG8gc29tZSBuaWNlIHZhbHVlcyBsaWtlIHRoZSBjb3VudGVyIG5vdCBiZWluZyBj bG9zZQo+ID4gKyAqIHRvIHRoZSBlZGdlLCBhbmQgdGhlIGNvbnRyb2wgcmVnaXN0ZXIgbWFza2Vk IGFuZCBkaXNhYmxlZC4KPiA+ICsgKi8KPiA+ICtzdGF0aWMgdm9pZCByZXNldF90aW1lcl9zdGF0 ZSh1aW50NjRfdCBjbnQpCj4gPiArewo+ID4gKwlTRVRfQ09VTlRFUihjbnQpOwo+ID4gKwlUSU1F Ul9TRVRfQ1RMKENUTF9JTUFTSyk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lkIHRlc3Rf dGltZXJfeHZhbCh1aW50NjRfdCB4dmFsLCB0aW1lcl92aWV3X3QgdHYsIHdmaV9tZXRob2RfdCB3 bSwKPiA+ICsJCWJvb2wgcmVzZXRfc3RhdGUsIHVpbnQ2NF90IHJlc2V0X2NudCkKPiA+ICt7Cj4g PiArCWxvY2FsX2lycV9kaXNhYmxlKCk7Cj4gPiArCj4gPiArCWlmIChyZXNldF9zdGF0ZSkKPiA+ ICsJCXJlc2V0X3RpbWVyX3N0YXRlKHJlc2V0X2NudCk7Cj4gPiArCj4gPiArCXNldF94dmFsX2ly cSh4dmFsLCBDVExfRU5BQkxFLCB0dik7Cj4gPiArCXdtKCk7Cj4gPiArCj4gPiArCUFTU0VSVF9J UlFTX0hBTkRMRURfMigxLCB0diwgd20pOwo+IAo+IFByaW50aW5nIHRoZSBmdW5jdGlvbiBwb2lu dGVyIHByb2JhYmx5IGlzbid0IHRvbyBoZWxwZnVsIHcvbyBpbnNwZWN0aW5nCj4gdGhlIGJpbmFy eS4KPiAKClRoaXMgaGFzIGJlZW4gdmVyeSB1c2VmdWwgb24gbXkgc2lkZSwgZm9yIG15IG93biBk ZWJ1Z2dpbmcuIEJ1dCBJIGd1ZXNzCml0IGNhbiBiZSBkcm9wcGVkLgoKPiA+ICsJbG9jYWxfaXJx X2VuYWJsZSgpOwo+ID4gK30KPiA+ICsKPiA+ICsvKgo+ID4gKyAqIFRoZSB0ZXN0X3RpbWVyXyog ZnVuY3Rpb25zIHdpbGwgcHJvZ3JhbSB0aGUgdGltZXIsIHdhaXQgZm9yIGl0LCBhbmQgYXNzZXJ0 Cj4gPiArICogdGhlIGZpcmluZyBvZiB0aGUgY29ycmVjdCBJUlEuCj4gPiArICoKPiA+ICsgKiBU aGVzZSBmdW5jdGlvbnMgZG9uJ3QgaGF2ZSBhIHRpbWVvdXQgYW5kIHJldHVybiBhcyBzb29uIGFz IHRoZXkgcmVjZWl2ZSBhbgo+ID4gKyAqIElSUS4gVGhleSBjYW4gaGFuZyAoZm9yZXZlciksIHNv IHdlIHJlbHkgb24gaGF2aW5nIGEgdGltZW91dCBtZWNoYW5pc20gaW4KPiA+ICsgKiB0aGUgInJ1 bm5lciIsIGxpa2U6IHRvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2tzZWxmdGVzdC9ydW5uZXIuc2gu Cj4gPiArICovCj4gCj4gTGlmdCB0aGUgaGFuZyBjb21tZW50YXJ5IGludG8gdGhlIHRvcC1sZXZl bCBjb21tZW50Cj4gCj4gPiArc3RhdGljIHZvaWQgdGVzdF90aW1lcl9jdmFsKHVpbnQ2NF90IGN2 YWwsIHdmaV9tZXRob2RfdCB3bSwgYm9vbCByZXNldF9zdGF0ZSwKPiA+ICsJCXVpbnQ2NF90IHJl c2V0X2NudCkKPiA+ICt7Cj4gPiArCXRlc3RfdGltZXJfeHZhbChjdmFsLCBUSU1FUl9DVkFMLCB3 bSwgcmVzZXRfc3RhdGUsIHJlc2V0X2NudCk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lk IHRlc3RfdGltZXJfdHZhbChpbnQzMl90IHR2YWwsIHdmaV9tZXRob2RfdCB3bSwgYm9vbCByZXNl dF9zdGF0ZSwKPiA+ICsJCXVpbnQ2NF90IHJlc2V0X2NudCkKPiA+ICt7Cj4gPiArCXRlc3RfdGlt ZXJfeHZhbCgodWludDY0X3QpdHZhbCwgVElNRVJfVFZBTCwgd20sIHJlc2V0X3N0YXRlLCByZXNl dF9jbnQpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB0ZXN0X2Jhc2ljX2Z1bmN0aW9u YWxpdHkodm9pZCkKPiA+ICt7Cj4gPiArCWludDMyX3QgdHZhbCA9IChpbnQzMl90KW1zZWNfdG9f Y3ljbGVzKDEwKTsKPiA+ICsJdWludDY0X3QgY3ZhbDsKPiA+ICsJaW50IGk7Cj4gPiArCj4gPiAr CWZvcl9lYWNoX3dmaV9tZXRob2QoaSkgewo+ID4gKwkJd2ZpX21ldGhvZF90IHdtID0gd2ZpX21l dGhvZFtpXTsKPiA+ICsKPiA+ICsJCWN2YWwgPSBERUZfQ05UICsgbXNlY190b19jeWNsZXMoMTAp Owo+ID4gKwo+ID4gKwkJdGVzdF90aW1lcl9jdmFsKGN2YWwsIHdtLCB0cnVlLCBERUZfQ05UKTsK PiA+ICsJCXRlc3RfdGltZXJfdHZhbCh0dmFsLCB3bSwgdHJ1ZSwgREVGX0NOVCk7Cj4gPiArCX0K PiA+ICt9Cj4gPiArCj4gPiArLyoKPiA+ICsgKiBUaGlzIHRlc3QgY2hlY2tzIGJhc2ljIHRpbWVy IGJlaGF2aW9yIHdpdGhvdXQgYWN0dWFsbHkgZmlyaW5nIHRpbWVycywgdGhpbmdzCj4gPiArICog bGlrZTogdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGN2YWwgYW5kIHR2YWwsIHR2YWwgZG93bi1j b3VudGluZy4KPiA+ICsgKi8KPiA+ICtzdGF0aWMgdm9pZCB0aW1lcnNfc2FuaXR5X2NoZWNrcyhi b29sIHVzZV9zY2hlZCkKPiA+ICt7Cj4gPiArCXJlc2V0X3RpbWVyX3N0YXRlKERFRl9DTlQpOwo+ ID4gKwo+ID4gKwlsb2NhbF9pcnFfZGlzYWJsZSgpOwo+ID4gKwo+ID4gKwkvKiBjdmFsIGluIHRo ZSBwYXN0ICovCj4gPiArCVRJTUVSX1NFVF9DVkFMKFRJTUVSX0dFVF9DTlRDVCgpIC0gbXNlY190 b19jeWNsZXMoMTApKTsKPiA+ICsJaWYgKHVzZV9zY2hlZCkKPiA+ICsJCVVTRVJTUEFDRV9TQ0hF RFVMRSgpOwo+ID4gKwlHVUVTVF9BU1NFUlQoVElNRVJfR0VUX1RWQUwoKSA8IDApOwo+ID4gKwo+ ID4gKwkvKiB0dmFsIGluIHRoZSBwYXN0ICovCj4gPiArCVRJTUVSX1NFVF9UVkFMKC0xKTsKPiA+ ICsJaWYgKHVzZV9zY2hlZCkKPiA+ICsJCVVTRVJTUEFDRV9TQ0hFRFVMRSgpOwo+ID4gKwlHVUVT VF9BU1NFUlQoVElNRVJfR0VUX0NWQUwoKSA8IFRJTUVSX0dFVF9DTlRDVCgpKTsKPiA+ICsKPiA+ ICsJLyogdHZhbCBsYXJnZXIgdGhhbiBUVkFMX01BWC4gKi8KPiA+ICsJVElNRVJfU0VUX0NWQUwo VElNRVJfR0VUX0NOVENUKCkgKyBUVkFMX01BWCArIG1zZWNfdG9fY3ljbGVzKDEwKSk7Cj4gPiAr CWlmICh1c2Vfc2NoZWQpCj4gPiArCQlVU0VSU1BBQ0VfU0NIRURVTEUoKTsKPiA+ICsJR1VFU1Rf QVNTRVJUKFRJTUVSX0dFVF9UVkFMKCkgPD0gMCk7Cj4gPiArCj4gPiArCS8qCj4gPiArCSAqIHR2 YWwgbGFyZ2VyIHRoYW4gMiAqIFRWQUxfTUFYLgo+ID4gKwkgKiBUd2ljZSB0aGUgVFZBTF9NQVgg Y29tcGxldGVseSBsb29wcyBhcm91bmQgdGhlIFRWQUwuCj4gPiArCSAqLwo+ID4gKwlUSU1FUl9T RVRfQ1ZBTChUSU1FUl9HRVRfQ05UQ1QoKSArIDJVTEwgKiBUVkFMX01BWCArIG1zZWNfdG9fY3lj bGVzKDEwKSk7Cj4gPiArCWlmICh1c2Vfc2NoZWQpCj4gPiArCQlVU0VSU1BBQ0VfU0NIRURVTEUo KTsKPiA+ICsJR1VFU1RfQVNTRVJUXzEoVElNRVJfR0VUX1RWQUwoKSA8PSBtc2VjX3RvX2N5Y2xl cygxMCksIFRJTUVSX0dFVF9UVkFMKCkpOwo+ID4gKwo+ID4gKwkvKiBuZWdhdGl2ZSB0dmFsIHRo YXQgcm9sbG92ZXJzIGZyb20gMC4gKi8KPiA+ICsJU0VUX0NPVU5URVIobXNlY190b19jeWNsZXMo MSkpOwo+ID4gKwlUSU1FUl9TRVRfVFZBTCgtMSAqIG1zZWNfdG9fY3ljbGVzKDEwKSk7Cj4gPiAr CWlmICh1c2Vfc2NoZWQpCj4gPiArCQlVU0VSU1BBQ0VfU0NIRURVTEUoKTsKPiA+ICsJR1VFU1Rf QVNTRVJUKFRJTUVSX0dFVF9DVkFMKCkgPj0gKENWQUxfTUFYIC0gbXNlY190b19jeWNsZXMoOSkp KTsKPiA+ICsKPiA+ICsJLyogdHZhbCBzaG91bGQga2VlcCBkb3duLWNvdW50aW5nIGZyb20gMCB0 byAtMS4gKi8KPiA+ICsJVElNRVJfU0VUX1RWQUwoMCk7Cj4gPiArCS8qIFdlIGp1c3QgbmVlZCAx IGN5Y2xlIHRvIHBhc3MuICovCj4gPiArCWlzYigpOwo+ID4gKwlHVUVTVF9BU1NFUlQoVElNRVJf R0VUX1RWQUwoKSA8IDApOwo+ID4gKwo+ID4gKwlsb2NhbF9pcnFfZW5hYmxlKCk7Cj4gPiArCj4g PiArCS8qIE1hc2sgYW5kIGRpc2FibGUgYW55IHBlbmRpbmcgdGltZXIuICovCj4gPiArCVRJTUVS X1NFVF9DVEwoQ1RMX0lNQVNLKTsKPiA+ICt9Cj4gCj4gVGhlcmUgYXJlIGluc3RhbmNlcyBvZiBu b3Qtc28tc2FuZSBHZW5lcmljIFRpbWVycywgc3VjaCBhcyB0aGUgWEdlbmUtMQo+IHRoYXQgcHJv YmFibHkgd29uJ3QgYmUgZnVuIHRvIHRlc3QuIE1hcmMgd291bGQga25vdyBtb3JlIGFib3V0IHRo aXMsIGJ1dAo+IHRoZXJlIG1heSBuZWVkIHRvIGJlIGEgZGVueWxpc3Qgb2YgYmFkIGltcGxlbWVu dGF0aW9ucy4KPgoKQWN0dWFsbHksIFFFTVUtVENHIGZhaWxzIHNvbWUgdGVzdHMgKHJlbGF0ZWQg dG8gcm9sbG92ZXJzKS4gSSBoYWQgYQpjb21tbWl0IHRvIGFkZCBhIGNtZGxpbmUgYXJnIHRvIG5v dCBydW4gdGhvc2UuIEkgZGVjaWRlZCBpbiBmYXZvcgpvZiBmYWlsaW5nIGluIHRob3NlIGNhc2Vz IGFzIHdlbGwuCgo+ID4gK3N0YXRpYyB2b2lkIHRlc3RfdGltZXJzX3Nhbml0eV9jaGVja3Modm9p ZCkKPiA+ICt7Cj4gPiArCXRpbWVyc19zYW5pdHlfY2hlY2tzKGZhbHNlKTsKPiA+ICsJLyogQ2hl Y2sgaG93IEtWTSBzYXZlcy9yZXN0b3JlcyB0aGVzZSBlZGdlLWNhc2UgdmFsdWVzLiAqLwo+ID4g Kwl0aW1lcnNfc2FuaXR5X2NoZWNrcyh0cnVlKTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZv aWQgZ3Vlc3RfcnVuX2l0ZXJhdGlvbih2b2lkKQo+ID4gK3sKPiA+ICsJdGVzdF9iYXNpY19mdW5j dGlvbmFsaXR5KCk7Cj4gPiArCXRlc3RfdGltZXJzX3Nhbml0eV9jaGVja3MoKTsKPiA+ICt9Cj4g PiArCj4gPiArc3RhdGljIHZvaWQgZ3Vlc3RfY29kZSh2b2lkKQo+ID4gK3sKPiA+ICsJaW50IGk7 Cj4gPiArCj4gPiArCWxvY2FsX2lycV9kaXNhYmxlKCk7Cj4gPiArCj4gPiArCWdpY19pbml0KEdJ Q19WMywgMSwgKHZvaWQgKilHSUNEX0JBU0VfR1BBLCAodm9pZCAqKUdJQ1JfQkFTRV9HUEEpOwo+ ID4gKwo+ID4gKwlUSU1FUl9TRVRfQ1RMKENUTF9JTUFTSyk7Cj4gPiArCXRpbWVyX3NldF9jdGwo UEhZU0lDQUwsIENUTF9JTUFTSyk7Cj4gPiArCj4gPiArCWdpY19pcnFfZW5hYmxlKHZ0aW1lcl9p cnEpOwo+ID4gKwlnaWNfaXJxX2VuYWJsZShwdGltZXJfaXJxKTsKPiA+ICsJbG9jYWxfaXJxX2Vu YWJsZSgpOwo+ID4gKwo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgdGVzdF9hcmdzLml0ZXJhdGlvbnM7 IGkrKykgewo+ID4gKwkJR1VFU1RfU1lOQyhpKTsKPiA+ICsJCWd1ZXN0X3J1bl9pdGVyYXRpb24o KTsKPiA+ICsJfQo+ID4gKwo+ID4gKwlHVUVTVF9ET05FKCk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0 YXRpYyB2b2lkIG1pZ3JhdGVfc2VsZih1aW50MzJfdCBuZXdfcGNwdSkKPiA+ICt7Cj4gPiArCWlu dCByZXQ7Cj4gPiArCWNwdV9zZXRfdCBjcHVzZXQ7Cj4gPiArCXB0aHJlYWRfdCB0aHJlYWQ7Cj4g PiArCj4gPiArCXRocmVhZCA9IHB0aHJlYWRfc2VsZigpOwo+ID4gKwo+ID4gKwlDUFVfWkVSTygm Y3B1c2V0KTsKPiA+ICsJQ1BVX1NFVChuZXdfcGNwdSwgJmNwdXNldCk7Cj4gPiArCj4gPiArCXBy X2RlYnVnKCJNaWdyYXRpbmcgZnJvbSAldSB0byAldVxuIiwgc2NoZWRfZ2V0Y3B1KCksIG5ld19w Y3B1KTsKPiA+ICsKPiA+ICsJcmV0ID0gcHRocmVhZF9zZXRhZmZpbml0eV9ucCh0aHJlYWQsIHNp emVvZihjcHVzZXQpLCAmY3B1c2V0KTsKPiA+ICsKPiA+ICsJVEVTVF9BU1NFUlQocmV0ID09IDAs ICJGYWlsZWQgdG8gbWlncmF0ZSB0byBwQ1BVOiAldTsgcmV0OiAlZFxuIiwKPiA+ICsJCQluZXdf cGNwdSwgcmV0KTsKPiA+ICt9Cj4gPiArCj4gPiArLyoKPiA+ICsgKiBTZXQgdGhlIHR3byBwY3B1 cyB0aGF0IHRoZSB0ZXN0IHdpbGwgdXNlIHRvIGFsdGVybmF0ZSBiZXR3ZWVuLiBEZWZhdWx0IHRv Cj4gPiArICogdXNlIHRoZSBjdXJyZW50IGNwdSBhcyBwY3B1c1swXSBhbmQgdGhlIG9uZSByaWdo dCBhZnRlciBpbiB0aGUgYWZmaW5pdHkgc2V0Cj4gPiArICogYXMgcGNwdXNbMV0uCj4gPiArICov Cj4gPiArc3RhdGljIHZvaWQgc2V0X2RlZmF1bHRfcGNwdXModm9pZCkKPiA+ICt7Cj4gPiArCWlu dCBtYXgJPSBnZXRfbnByb2NzKCk7Cj4gPiArCWludCBjdXJyID0gc2NoZWRfZ2V0Y3B1KCk7Cj4g PiArCWNwdV9zZXRfdCBjcHVzZXQ7Cj4gPiArCWxvbmcgaTsKPiA+ICsKPiA+ICsJVEVTVF9BU1NF UlQobWF4ID4gMSwgIk5lZWQgYXQgbGVhc3QgMiBvbmxpbmUgcGNwdXMuIik7Cj4gCj4gU2hvdWxk IHRoZSB0ZXN0IHNraXAgKGluc3RlYWQgb2YgZmFpbCkgb24gc3VjaCBhIHByZWNvbmRpdGlvbj8K PgoKWWVzLCB0aGF0IHdvdWxkIGJlIG5pY2VyLCB3aWxsIGFkZCB0aGUgY2hlY2sgaW4gdjIuCgo+ ID4gKwlwY3B1c1swXSA9IGN1cnI7Cj4gPiArCj4gPiArCXNjaGVkX2dldGFmZmluaXR5KGdldHBp ZCgpLCBzaXplb2YoY3B1X3NldF90KSwgJmNwdXNldCk7Cj4gPiArCWZvciAoaSA9IChjdXJyICsg MSkgJSBDUFVfU0VUU0laRTsgaSAhPSBjdXJyOyBpID0gKGkgKyAxKSAlIENQVV9TRVRTSVpFKSB7 Cj4gPiArCQlpZiAoQ1BVX0lTU0VUKGksICZjcHVzZXQpKSB7Cj4gPiArCQkJcGNwdXNbMV0gPSBp Owo+ID4gKwkJCWJyZWFrOwo+ID4gKwkJfQo+ID4gKwl9Cj4gPiArCj4gPiArCVRFU1RfQVNTRVJU KHBjcHVzWzFdICE9IC0xLCAiQ291bGRuJ3QgZmluZCBhIHNlY29uZCBwY3B1LiIpOwo+ID4gKwlw cl9kZWJ1ZygicGNwdXM6ICVkICVkXG4iLCBwY3B1c1swXSwgcGNwdXNbMV0pOwo+ID4gK30KPiA+ ICsKPiA+ICtzdGF0aWMgdm9pZCBrdm1fc2V0X2NudHhjdChzdHJ1Y3Qga3ZtX3ZtICp2bSwgdWlu dDY0X3QgY250LCBlbnVtIGFyY2hfdGltZXIgdGltZXIpCj4gPiArewo+ID4gKwlURVNUX0FTU0VS VCh0aW1lciA9PSBWSVJUVUFMLAo+ID4gKwkJIk9ubHkgc3VwcG9ydHMgc2V0dGluZyB0aGUgdmly dHVhbCBjb3VudGVyIGZvciBub3cuIik7Cj4gPiArCj4gPiArCXN0cnVjdCBrdm1fb25lX3JlZyBy ZWcgPSB7Cj4gPiArCQkuaWQgPSBLVk1fUkVHX0FSTV9USU1FUl9DTlQsCj4gPiArCQkuYWRkciA9 ICh1aW50NjRfdCkmY250LAo+ID4gKwl9Owo+ID4gKwl2Y3B1X3NldF9yZWcodm0sIDAsICZyZWcp Owo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCBoYW5kbGVfc3luYyhzdHJ1Y3Qga3ZtX3Zt ICp2bSwgc3RydWN0IHVjYWxsICp1YykKPiA+ICt7Cj4gPiArCXN5bmNfY21kX3QgY21kID0gdWMt PmFyZ3NbMV07Cj4gPiArCXVpbnQ2NF90IHZhbCA9IHVjLT5hcmdzWzJdOwo+ID4gKwllbnVtIGFy Y2hfdGltZXIgdGltZXIgPSB1Yy0+YXJnc1szXTsKPiA+ICsKPiA+ICsJc3dpdGNoIChjbWQpIHsK PiA+ICsJY2FzZSBTRVRfUkVHX0tWTV9SRUdfQVJNX1RJTUVSX0NOVDoKPiA+ICsJCWt2bV9zZXRf Y250eGN0KHZtLCB2YWwsIHRpbWVyKTsKPiA+ICsJCWJyZWFrOwo+ID4gKwljYXNlIFVTRVJTUEFD RV9TQ0hFRF9ZSUVMRDoKPiA+ICsJCXNjaGVkX3lpZWxkKCk7Cj4gPiArCQlicmVhazsKPiA+ICsJ Y2FzZSBVU0VSU1BBQ0VfTUlHUkFURV9TRUxGOgo+ID4gKwkJbWlncmF0ZV9zZWxmKG5leHRfcGNw dSgpKTsKPiA+ICsJCWJyZWFrOwo+ID4gKwlkZWZhdWx0Ogo+ID4gKwkJYnJlYWs7Cj4gPiArCX0K PiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgdGVzdF9ydW4oc3RydWN0IGt2bV92bSAqdm0p Cj4gPiArewo+ID4gKwlzdHJ1Y3QgdWNhbGwgdWM7Cj4gPiArCWludCBzdGFnZSA9IDA7Cj4gPiAr Cj4gPiArCS8qIFN0YXJ0IG9uIHRoZSBmaXJzdCBwY3B1LiAqLwo+ID4gKwltaWdyYXRlX3NlbGYo cGNwdXNbMF0pOwo+ID4gKwo+ID4gKwlzeW5jX2dsb2JhbF90b19ndWVzdCh2bSwgdGVzdF9hcmdz KTsKPiA+ICsKPiA+ICsJZm9yIChzdGFnZSA9IDA7IDsgc3RhZ2UrKykgewo+ID4gKwkJdmNwdV9y dW4odm0sIFZDUFVJRCk7Cj4gPiArCQlzd2l0Y2ggKGdldF91Y2FsbCh2bSwgVkNQVUlELCAmdWMp KSB7Cj4gPiArCQljYXNlIFVDQUxMX1NZTkM6Cj4gPiArCQkJaGFuZGxlX3N5bmModm0sICZ1Yyk7 Cj4gPiArCQkJYnJlYWs7Cj4gPiArCQljYXNlIFVDQUxMX0RPTkU6Cj4gPiArCQkJZ290byBvdXQ7 Cj4gPiArCQljYXNlIFVDQUxMX0FCT1JUOgo+ID4gKwkJCVRFU1RfRkFJTCgiJXMgYXQgJXM6JWxk XG5cdHZhbHVlczogJWx1LCAlbHU7ICVsdSIsCj4gPiArCQkJCShjb25zdCBjaGFyICopdWMuYXJn c1swXSwgX19GSUxFX18sIHVjLmFyZ3NbMV0sCj4gPiArCQkJCXVjLmFyZ3NbMl0sIHVjLmFyZ3Nb M10sIHVjLmFyZ3NbNF0pOwo+ID4gKwkJCWdvdG8gb3V0Owo+ID4gKwkJZGVmYXVsdDoKPiA+ICsJ CQlURVNUX0ZBSUwoIlVuZXhwZWN0ZWQgZ3Vlc3QgZXhpdFxuIik7Cj4gPiArCQl9Cj4gPiArCX0K PiA+ICsKPiA+ICtvdXQ6Cj4gPiArCXJldHVybjsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZv aWQgdGVzdF9pbml0X3RpbWVyX2lycShzdHJ1Y3Qga3ZtX3ZtICp2bSkKPiA+ICt7Cj4gPiArCWlu dCB2Y3B1X2ZkID0gdmNwdV9nZXRfZmQodm0sIFZDUFVJRCk7Cj4gPiArCj4gPiArCWt2bV9kZXZp Y2VfYWNjZXNzKHZjcHVfZmQsIEtWTV9BUk1fVkNQVV9USU1FUl9DVFJMLAo+ID4gKwkJCUtWTV9B Uk1fVkNQVV9USU1FUl9JUlFfUFRJTUVSLCAmcHRpbWVyX2lycSwgZmFsc2UpOwo+ID4gKwlrdm1f ZGV2aWNlX2FjY2Vzcyh2Y3B1X2ZkLCBLVk1fQVJNX1ZDUFVfVElNRVJfQ1RSTCwKPiA+ICsJCQlL Vk1fQVJNX1ZDUFVfVElNRVJfSVJRX1ZUSU1FUiwgJnZ0aW1lcl9pcnEsIGZhbHNlKTsKPiA+ICsK PiA+ICsJc3luY19nbG9iYWxfdG9fZ3Vlc3Qodm0sIHB0aW1lcl9pcnEpOwo+ID4gKwlzeW5jX2ds b2JhbF90b19ndWVzdCh2bSwgdnRpbWVyX2lycSk7Cj4gPiArCj4gPiArCXByX2RlYnVnKCJwdGlt ZXJfaXJxOiAlZDsgdnRpbWVyX2lycTogJWRcbiIsIHB0aW1lcl9pcnEsIHZ0aW1lcl9pcnEpOwo+ ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgc3RydWN0IGt2bV92bSAqdGVzdF92bV9jcmVhdGUodm9p ZCkKPiA+ICt7Cj4gPiArCXN0cnVjdCBrdm1fdm0gKnZtOwo+ID4gKwo+ID4gKwl2bSA9IHZtX2Ny ZWF0ZV9kZWZhdWx0KFZDUFVJRCwgMCwgZ3Vlc3RfY29kZSk7Cj4gPiArCj4gPiArCXZtX2luaXRf ZGVzY3JpcHRvcl90YWJsZXModm0pOwo+ID4gKwl2bV9pbnN0YWxsX2V4Y2VwdGlvbl9oYW5kbGVy KHZtLCBWRUNUT1JfSVJRX0NVUlJFTlQsIGd1ZXN0X2lycV9oYW5kbGVyKTsKPiA+ICsKPiA+ICsJ dmNwdV9pbml0X2Rlc2NyaXB0b3JfdGFibGVzKHZtLCAwKTsKPiA+ICsKPiA+ICsJdWNhbGxfaW5p dCh2bSwgTlVMTCk7Cj4gPiArCXRlc3RfaW5pdF90aW1lcl9pcnEodm0pOwo+ID4gKwl2Z2ljX3Yz X3NldHVwKHZtLCAxLCA2NCwgR0lDRF9CQVNFX0dQQSwgR0lDUl9CQVNFX0dQQSk7Cj4gCj4gVGhl IHRlc3Qgc2hvdWxkIHByb2JhYmx5IHNraXAgaWYgR0lDdjMgaXNuJ3Qgc3VwcG9ydGVkLCBsaWtl IGNvbW1pdCA0NTZmODllMDkyOGEKPiAoIktWTTogc2VsZnRlc3RzOiBhYXJjaDY0OiBTa2lwIHRl c3RzIGlmIHdlIGNhbid0IGNyZWF0ZSBhIHZnaWMtdjMiKQo+CgpBY2ssIHdpbGwgYWRkIHRoZSBj aGVjayBpbiB2Mi4KCj4gPiArCXJldHVybiB2bTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZv aWQgdGVzdF9wcmludF9oZWxwKGNoYXIgKm5hbWUpCj4gPiArewo+ID4gKwlwcl9pbmZvKCJVc2Fn ZTogJXMgWy1oXSBbLWkgaXRlcmF0aW9uc10gWy13XSBbLXAgcGNwdTEscGNwdTJdXG4iLAo+ID4g KwkJbmFtZSk7Cj4gPiArCXByX2luZm8oIlx0LWk6IE51bWJlciBvZiBpdGVyYXRpb25zIChkZWZh dWx0OiAldSlcbiIsCj4gPiArCQlOUl9URVNUX0lURVJTX0RFRik7Cj4gPiArCXByX2luZm8oIlx0 LXA6IFBhaXIgb2YgcGNwdXMgZm9yIHRoZSB2Y3B1cyB0byBhbHRlcm5hdGUgYmV0d2Vlbi4gIgo+ ID4gKwkJIkRlZmF1bHRzIHRvIHVzZSB0aGUgY3VycmVudCBjcHUgYW5kIHRoZSBvbmUgcmlnaHQg YWZ0ZXIgIgo+ID4gKwkJImluIHRoZSBhZmZpbml0eSBzZXQuXG4iKTsKPiA+ICsJcHJfaW5mbygi XHQtaDogUHJpbnQgdGhpcyBoZWxwIG1lc3NhZ2VcbiIpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0 aWMgYm9vbCBwYXJzZV9hcmdzKGludCBhcmdjLCBjaGFyICphcmd2W10pCj4gPiArewo+ID4gKwlp bnQgb3B0LCByZXQ7Cj4gPiArCj4gPiArCXdoaWxlICgob3B0ID0gZ2V0b3B0KGFyZ2MsIGFyZ3Ys ICJoaTpwOiIpKSAhPSAtMSkgewo+ID4gKwkJc3dpdGNoIChvcHQpIHsKPiA+ICsJCWNhc2UgJ2kn Ogo+ID4gKwkJCXRlc3RfYXJncy5pdGVyYXRpb25zID0gYXRvaShvcHRhcmcpOwo+ID4gKwkJCWlm ICh0ZXN0X2FyZ3MuaXRlcmF0aW9ucyA8PSAwKSB7Cj4gPiArCQkJCXByX2luZm8oIlBvc2l0aXZl IHZhbHVlIG5lZWRlZCBmb3IgLWlcbiIpOwo+ID4gKwkJCQlnb3RvIGVycjsKPiA+ICsJCQl9Cj4g PiArCQkJYnJlYWs7Cj4gPiArCQljYXNlICdwJzoKPiA+ICsJCQlyZXQgPSBzc2NhbmYob3B0YXJn LCAiJXUsJXUiLCAmcGNwdXNbMF0sICZwY3B1c1sxXSk7Cj4gPiArCQkJaWYgKHJldCAhPSAyKSB7 Cj4gPiArCQkJCXByX2luZm8oIkludmFsaWQgcGNwdXMgcGFpciIpOwo+ID4gKwkJCQlnb3RvIGVy cjsKPiA+ICsJCQl9Cj4gPiArCQkJYnJlYWs7Cj4gPiArCQljYXNlICdoJzoKPiA+ICsJCWRlZmF1 bHQ6Cj4gPiArCQkJZ290byBlcnI7Cj4gPiArCQl9Cj4gPiArCX0KPiA+ICsKPiA+ICsJcmV0dXJu IHRydWU7Cj4gPiArCj4gPiArZXJyOgo+ID4gKwl0ZXN0X3ByaW50X2hlbHAoYXJndlswXSk7Cj4g PiArCXJldHVybiBmYWxzZTsKPiA+ICt9Cj4gPiArCj4gPiAraW50IG1haW4oaW50IGFyZ2MsIGNo YXIgKmFyZ3ZbXSkKPiA+ICt7Cj4gPiArCXN0cnVjdCBrdm1fdm0gKnZtOwo+ID4gKwo+ID4gKwkv KiBUZWxsIHN0ZG91dCBub3QgdG8gYnVmZmVyIGl0cyBjb250ZW50ICovCj4gPiArCXNldGJ1Zihz dGRvdXQsIE5VTEwpOwo+ID4gKwo+ID4gKwlpZiAoIXBhcnNlX2FyZ3MoYXJnYywgYXJndikpCj4g PiArCQlleGl0KEtTRlRfU0tJUCk7Cj4gPiArCj4gPiArCWlmIChwY3B1c1swXSA9PSAtMSB8fCBw Y3B1c1sxXSA9PSAtMSkKPiA+ICsJCXNldF9kZWZhdWx0X3BjcHVzKCk7Cj4gPiArCj4gPiArCXZt ID0gdGVzdF92bV9jcmVhdGUoKTsKPiA+ICsJdGVzdF9ydW4odm0pOwo+ID4gKwlrdm1fdm1fZnJl ZSh2bSk7Cj4gPiArCj4gPiArCXJldHVybiAwOwo+ID4gK30KPiA+IC0tIAo+ID4gMi4zNS4xLjU3 NC5nNWQzMGM3M2JmYi1nb29nCj4KClRoYW5rcyBmb3IgdGhlIHJldmlldyEKCldpbGwgd29yayBv biB2Mi4KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18Ka3Zt YXJtIG1haWxpbmcgbGlzdAprdm1hcm1AbGlzdHMuY3MuY29sdW1iaWEuZWR1Cmh0dHBzOi8vbGlz dHMuY3MuY29sdW1iaWEuZWR1L21haWxtYW4vbGlzdGluZm8va3ZtYXJtCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B4F5C433F5 for ; Wed, 2 Mar 2022 21:25:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245085AbiCBV0U (ORCPT ); Wed, 2 Mar 2022 16:26:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49732 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236363AbiCBV0T (ORCPT ); Wed, 2 Mar 2022 16:26:19 -0500 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0E93BECE7 for ; Wed, 2 Mar 2022 13:25:33 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id 9so2698250pll.6 for ; Wed, 02 Mar 2022 13:25:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=DSJKv4X7KgGu7FsUU22pIWhfKTSJUinwycebGO+swSE=; b=Z4bxuyoYzgxeSWKrJzJD6y7wbX5C5E4GHeIK8jVrI/c2ZKY/oMSQYZI/Zw24lrTRMV 2Ao22Y/Vml0vHa938pDj53pm+0zcU/P8Rwm4MqacRApwFjS7++0L/L6SbDQ9HrP7asXr PhaXe3irMhgcY95iI9u04xdIaY65dkC/Xxpa58sK52VzbuixmQCxNHORCdbvUa/Xp75k GOmyJR41dm6BNB2yPwIqcqy13kDf516xAUxEWA7FYI+xLQKHI8reKV3E4CKMM+UyQLFe BUpKqnPMKYPQp1QvTTDlvQRcYhBO6PUGhfdPrxg00F093X7IUU46tSe34g0ZthWEOS/u /AAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=DSJKv4X7KgGu7FsUU22pIWhfKTSJUinwycebGO+swSE=; b=QINPl3UlGtM1tQ54E36WTI1Zz3n0p8bTOOYYAxHs56723DmVbE818fVvtil23YjQTT m/mdNCUpFppRFLPg+EEu1sbIpis0qdNdAIyiw0JcnQgj28L7Gx4T9v7bQO3V8jVp/EKQ m4iLaQwWLu4E8Ei7TFa7VpWkk8UyG9t8/+5FOt4OmppnDPnOMHelL8OIlk9l7UzVnBTG FYvK98ujHJNjwL5GcecSQTKLxbEt+hDXMJH1M2CnH6pfP/YQAzBmcyV/U+sEYbmN6Pt7 6ID1nGad4fSuxwD2pmpcUQlWLgC9PRpFJ1wckv/PLbZe1H0ad1TtnMufUZT9usDfaVst 8EIw== X-Gm-Message-State: AOAM531Idr0r1pw4h9YmUk/syFSFZ2l7tOKzQCd53FPahyRg+FzyQsna JksFS0LoKyeAXIwy/3AaDoOr9A== X-Google-Smtp-Source: ABdhPJzooJsjmsWOCrjFPjKotLonTPkYm1cpFO1qaqpRcNgGLBSKs2YDLSRt8/7VYTEXGcrNnHgXZw== X-Received: by 2002:a17:903:124a:b0:151:99fe:1a10 with SMTP id u10-20020a170903124a00b0015199fe1a10mr4031232plh.87.1646256332860; Wed, 02 Mar 2022 13:25:32 -0800 (PST) Received: from google.com (150.12.83.34.bc.googleusercontent.com. [34.83.12.150]) by smtp.gmail.com with ESMTPSA id f13-20020a056a001acd00b004f0f9a967basm104045pfv.100.2022.03.02.13.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Mar 2022 13:25:32 -0800 (PST) Date: Wed, 2 Mar 2022 13:25:28 -0800 From: Ricardo Koller To: Oliver Upton Cc: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, pbonzini@redhat.com, maz@kernel.org, alexandru.elisei@arm.com, eric.auger@redhat.com, reijiw@google.com, rananta@google.com Subject: Re: [PATCH 2/3] KVM: arm64: selftests: add arch_timer_edge_cases Message-ID: References: <20220302172144.2734258-1-ricarkol@google.com> <20220302172144.2734258-3-ricarkol@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Hi Oliver, On Wed, Mar 02, 2022 at 08:45:53PM +0000, Oliver Upton wrote: > Hi Ricardo, > > On Wed, Mar 02, 2022 at 09:21:43AM -0800, Ricardo Koller wrote: > > Add an arch_timer edge-cases selftest. For now, just add some basic > > sanity checks, and some stress conditions (like waiting for the timers > > while re-scheduling the vcpu). The next commit will add the actual edge > > case tests. > > > > This test fails without a867e9d0cc1 "KVM: arm64: Don't miss pending > > interrupts for suspended vCPU". > > > > Testing timer correctness is extremely challenging to do without > inherent flakiness. I have some concerns about the expectations that a > timer IRQ should fire in a given amount of time, as it is possible to > flake for any number of benign reasons (such as high CPU load in the > host). > > While the architecture may suggest that the timer should fire as soon as > CVAL is met: > > TimerConditionMet = (((Counter[63:0] – Offset[63:0])[63:0] - CompareValue[63:0]) >= 0) > > However, the architecture is extremely imprecise as to when an interrupt > should be taken: > > In the absence of a specific requirement to take an interrupt, the > architecture only requires that unmasked pending interrupts are taken > in finite time. [DDI0487G.b D1.13.4 "Prioritization and recognition of > interrupts"] > > It seems to me that the only thing we can positively assert is that a > timer interrupt should never be taken early. Now -- I agree that there > is value in testing that the interrupt be taken in bounded time, but its > hard to pick a good value for it. Yes, a timer that never fires passes the test, but it's not very useful. I saw delay issues immediately after testing with QEMU. I've been played with values and found that 1ms is enough for all of my runs (QEMU included) to pass (10000 iterations concurrently on all my 64 cpus). I just checked in the fast model and 1ms seems to be enough as well (although I didn't check for so long). /* 1ms sounds a bit excessive, but QEMU-TCG is slow. */ #define TEST_MARGIN_US 1000ULL > > Perhaps documenting the possibility of flakes in the test is warranted, > along with some knobs to adjust these values for any particularly bad > implementation. What about having a cmdline arg to enable those tests? > > > Reviewed-by: Reiji Watanabe > > Reviewed-by: Raghavendra Rao Ananta > > Signed-off-by: Ricardo Koller > > --- > > tools/testing/selftests/kvm/.gitignore | 1 + > > tools/testing/selftests/kvm/Makefile | 1 + > > .../kvm/aarch64/arch_timer_edge_cases.c | 634 ++++++++++++++++++ > > 3 files changed, 636 insertions(+) > > create mode 100644 tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c > > > > diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore > > index dce7de7755e6..8f7e0123dd28 100644 > > --- a/tools/testing/selftests/kvm/.gitignore > > +++ b/tools/testing/selftests/kvm/.gitignore > > @@ -1,5 +1,6 @@ > > # SPDX-License-Identifier: GPL-2.0-only > > /aarch64/arch_timer > > +/aarch64/arch_timer_edge_cases > > /aarch64/debug-exceptions > > /aarch64/get-reg-list > > /aarch64/psci_cpu_on_test > > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile > > index 0e4926bc9a58..17a0f32cfc91 100644 > > --- a/tools/testing/selftests/kvm/Makefile > > +++ b/tools/testing/selftests/kvm/Makefile > > @@ -101,6 +101,7 @@ TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test > > TEST_GEN_PROGS_x86_64 += system_counter_offset_test > > > > TEST_GEN_PROGS_aarch64 += aarch64/arch_timer > > +TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases > > TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions > > TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list > > TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test > > diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c b/tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c > > new file mode 100644 > > index 000000000000..48c886bce849 > > --- /dev/null > > +++ b/tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c > > @@ -0,0 +1,634 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * arch_timer_edge_cases.c - Tests the aarch64 timer IRQ functionality. > > + * > > + * Copyright (c) 2021, Google LLC. > > + */ > > + > > +#define _GNU_SOURCE > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "kvm_util.h" > > +#include "processor.h" > > +#include "delay.h" > > +#include "arch_timer.h" > > +#include "gic.h" > > +#include "vgic.h" > > + > > +#define VCPUID 0 > > + > > +#define msecs_to_usecs(msec) ((msec) * 1000LL) > > + > > +#define CVAL_MAX ~0ULL > > +/* tval is a signed 32-bit int. */ > > +#define TVAL_MAX INT_MAX > > +#define TVAL_MIN INT_MIN > > + > > +#define GICD_BASE_GPA 0x8000000ULL > > +#define GICR_BASE_GPA 0x80A0000ULL > > + > > +/* After how much time we say there is no IRQ. */ > > +#define TIMEOUT_NO_IRQ_US msecs_to_usecs(50) > > + > > +/* 1ms sounds a bit excessive, but QEMU-TCG is slow. */ > > +#define TEST_MARGIN_US 1000ULL > > + > > +/* A nice counter value to use as the starting one for most tests. */ > > +#define DEF_CNT (CVAL_MAX / 2) > > + > > +/* Number of runs. */ > > +#define NR_TEST_ITERS_DEF 5 > > + > > +/* Shared with IRQ handler. */ > > +volatile struct test_vcpu_shared_data { > > + int handled; > > +} shared_data; > > + > > +struct test_args { > > + /* Virtual or physical timer and counter tests. */ > > + enum arch_timer timer; > > + /* Number of iterations. */ > > + int iterations; > > +}; > > + > > +struct test_args test_args = { > > + /* Only testing VIRTUAL timers for now. */ > > + .timer = VIRTUAL, > > + .iterations = NR_TEST_ITERS_DEF, > > +}; > > + > > +static int vtimer_irq, ptimer_irq; > > + > > +typedef enum sync_cmd { > > + SET_REG_KVM_REG_ARM_TIMER_CNT = 100001, > > + USERSPACE_SCHED_YIELD, > > + USERSPACE_MIGRATE_SELF, > > +} sync_cmd_t; > > + > > +typedef void (*wfi_method_t)(void); > > + > > nit: the name suggests to me a WFI in the architectural sense, but it > appears polling is employed in certain implementations. Perhaps call it > wait_method_t? > > > +static void wait_for_non_spurious_irq(void); > > +static void wait_poll_for_irq(void); > > +static void wait_sched_poll_for_irq(void); > > +static void wait_migrate_poll_for_irq(void); > > + > > +wfi_method_t wfi_method[] = { > > + wait_for_non_spurious_irq, > > + wait_poll_for_irq, > > + wait_sched_poll_for_irq, > > + wait_migrate_poll_for_irq, > > +}; > > + > > +#define for_each_wfi_method(i) \ > > + for ((i) = 0; (i) < ARRAY_SIZE(wfi_method); (i)++) > > nit: for simple iterators such as this, I would prefer it be open-coded > instead of defined in a macro. > > > +typedef enum timer_view { > > + TIMER_CVAL = 1, > > nit: do we care about the enumeration value? Same goes for enum > sync_cmd. > > > + TIMER_TVAL, > > +} timer_view_t; > > nit: drop the typedef and just refer to the enum type explicitly. I'd > recommend this for other enums in this test as well. > > > + > > +/* Pair of pcpus for the test to alternate between. */ > > +static int pcpus[2] = {-1, -1}; > > +static int pcpus_idx; > > + > > +static uint32_t next_pcpu(void) > > +{ > > + pcpus_idx = 1 - pcpus_idx; > > + return pcpus[pcpus_idx]; > > +} > > + > > +#define ASSERT_IRQS_HANDLED_2(__nr, arg1, arg2) do { \ > > + int __h = shared_data.handled; \ > > + GUEST_ASSERT_4(__h == (__nr), __h, __nr, arg1, arg2); \ > > +} while (0) > > + > > +#define ASSERT_IRQS_HANDLED_1(__nr, arg1) \ > > + ASSERT_IRQS_HANDLED_2((__nr), arg1, 0) > > + > > +#define ASSERT_IRQS_HANDLED(__nr) \ > > + ASSERT_IRQS_HANDLED_2((__nr), 0, 0) > > + > > +#define TIMER_GET_CTL() \ > > + timer_get_ctl(test_args.timer) > > + > > +#define TIMER_SET_CTL(__ctl) \ > > + timer_set_ctl(test_args.timer, (__ctl)) > > + > > +#define TIMER_SET_CVAL(__cval) \ > > + timer_set_cval(test_args.timer, (__cval)) > > + > > +#define TIMER_SET_TVAL(__tval) \ > > + timer_set_tval(test_args.timer, (__tval)) > > + > > +#define TIMER_GET_CVAL() \ > > + timer_get_cval(test_args.timer) > > + > > +#define TIMER_GET_TVAL() \ > > + timer_get_tval(test_args.timer) > > + > > +#define TIMER_GET_CNTCT() \ > > + timer_get_cntct(test_args.timer) > > It might be cleaner to avoid these macro indirections and just have the > caller pass test_args.timer on its own. Could use a local variable in > the caller body to avoid referencing the struct every time. > > > +#define __SET_COUNTER(__ctr, __t) \ > > + GUEST_SYNC_ARGS(SET_REG_KVM_REG_ARM_TIMER_CNT, (__ctr), (__t), 0, 0) > > + > > +#define SET_COUNTER(__ctr) \ > > + __SET_COUNTER((__ctr), test_args.timer) > > + > > +#define USERSPACE_CMD(__cmd) \ > > + GUEST_SYNC_ARGS(__cmd, 0, 0, 0, 0) > > + > > +#define USERSPACE_SCHEDULE() \ > > + USERSPACE_CMD(USERSPACE_SCHED_YIELD) > > + > > +#define USERSPACE_MIGRATE_VCPU() \ > > + USERSPACE_CMD(USERSPACE_MIGRATE_SELF) > > + > > +#define IAR_SPURIOUS 1023 > > + > > how about INTID_SPURIOUS? Also, this is an invariant in the GIC > architecture, so maybe hoist it into the selftests GIC headers. > > > +static void guest_irq_handler(struct ex_regs *regs) > > +{ > > + unsigned int intid = gic_get_and_ack_irq(); > > + uint64_t cnt, cval; > > + uint32_t ctl; > > + > > + GUEST_ASSERT(gic_irq_get_pending(intid)); > > + > > + if (intid == IAR_SPURIOUS) > > + return; > > + > > + ctl = TIMER_GET_CTL(); > > + cnt = TIMER_GET_CNTCT(); > > + cval = TIMER_GET_CVAL(); > > + > > + GUEST_ASSERT_1(ctl & CTL_ISTATUS, ctl); > > + > > + /* Disable and mask the timer. */ > > + TIMER_SET_CTL(CTL_IMASK); > > + GUEST_ASSERT(!gic_irq_get_pending(intid)); > > + > > + shared_data.handled++; > > + > > + GUEST_ASSERT_2(cnt >= cval, cnt, cval); > > + > > + gic_set_eoi(intid); > > +} > > + > > +static void set_cval_irq(uint64_t cval_cycles, uint32_t ctl) > > +{ > > + shared_data.handled = 0; > > + TIMER_SET_CVAL(cval_cycles); > > + TIMER_SET_CTL(ctl); > > +} > > + > > +static void set_tval_irq(uint64_t tval_cycles, uint32_t ctl) > > +{ > > + shared_data.handled = 0; > > + TIMER_SET_TVAL(tval_cycles); > > + TIMER_SET_CTL(ctl); > > +} > > + > > +static void set_xval_irq(uint64_t xval, uint32_t ctl, timer_view_t tv) > > nit: how about program_timer_irq(). > > > +{ > > + switch (tv) { > > + case TIMER_CVAL: > > + set_cval_irq(xval, ctl); > > nit: just inline these helpers into the switch statement body. > > > + break; > > + case TIMER_TVAL: > > + set_tval_irq(xval, ctl); > > + break; > > + default: > > + GUEST_ASSERT(0); > > + } > > +} > > + > > +/* > > + * Should be called with IRQs masked. > > + * > > + * Note that this can hang forever, so we rely on having a timeout mechanism in > > + * the "runner", like: tools/testing/selftests/kselftest/runner.sh. > > + */ > > +static void wait_for_non_spurious_irq(void) > > +{ > > + int h; > > + > > + for (h = shared_data.handled; h == shared_data.handled;) { > > + asm volatile("wfi\n" > > + "msr daifclr, #2\n" > > + /* handle IRQ */ > > + "msr daifset, #2\n" > > + : : : "memory"); > > + } > > +} > > + > > +/* > > + * Wait for an non-spurious IRQ by polling in the guest (userspace=0) or in > > + * userspace (e.g., userspace=1 and userspace_cmd=USERSPACE_SCHED_YIELD). > > + * > > + * Should be called with IRQs masked. Not really needed like the wfi above, but > > + * it should match the others. > > + * > > + * Note that this can hang forever, so we rely on having a timeout mechanism in > > + * the "runner", like: tools/testing/selftests/kselftest/runner.sh. > > + */ > > +static void poll_for_non_spurious_irq(bool userspace, sync_cmd_t userspace_cmd) > > +{ > > + int h; > > + > > + h = shared_data.handled; > > + > > + local_irq_enable(); > > + while (h == shared_data.handled) { > > + if (userspace) > > + USERSPACE_CMD(userspace_cmd); > > + else > > + cpu_relax(); > > + } > > + local_irq_disable(); > > +} > > + > > +static void wait_poll_for_irq(void) > > +{ > > + poll_for_non_spurious_irq(false, -1); > > +} > > + > > +static void wait_sched_poll_for_irq(void) > > +{ > > + poll_for_non_spurious_irq(true, USERSPACE_SCHED_YIELD); > > +} > > + > > +static void wait_migrate_poll_for_irq(void) > > +{ > > + poll_for_non_spurious_irq(true, USERSPACE_MIGRATE_SELF); > > +} > > + > > +/* > > + * Reset the timer state to some nice values like the counter not being close > > + * to the edge, and the control register masked and disabled. > > + */ > > +static void reset_timer_state(uint64_t cnt) > > +{ > > + SET_COUNTER(cnt); > > + TIMER_SET_CTL(CTL_IMASK); > > +} > > + > > +static void test_timer_xval(uint64_t xval, timer_view_t tv, wfi_method_t wm, > > + bool reset_state, uint64_t reset_cnt) > > +{ > > + local_irq_disable(); > > + > > + if (reset_state) > > + reset_timer_state(reset_cnt); > > + > > + set_xval_irq(xval, CTL_ENABLE, tv); > > + wm(); > > + > > + ASSERT_IRQS_HANDLED_2(1, tv, wm); > > Printing the function pointer probably isn't too helpful w/o inspecting > the binary. > This has been very useful on my side, for my own debugging. But I guess it can be dropped. > > + local_irq_enable(); > > +} > > + > > +/* > > + * The test_timer_* functions will program the timer, wait for it, and assert > > + * the firing of the correct IRQ. > > + * > > + * These functions don't have a timeout and return as soon as they receive an > > + * IRQ. They can hang (forever), so we rely on having a timeout mechanism in > > + * the "runner", like: tools/testing/selftests/kselftest/runner.sh. > > + */ > > Lift the hang commentary into the top-level comment > > > +static void test_timer_cval(uint64_t cval, wfi_method_t wm, bool reset_state, > > + uint64_t reset_cnt) > > +{ > > + test_timer_xval(cval, TIMER_CVAL, wm, reset_state, reset_cnt); > > +} > > + > > +static void test_timer_tval(int32_t tval, wfi_method_t wm, bool reset_state, > > + uint64_t reset_cnt) > > +{ > > + test_timer_xval((uint64_t)tval, TIMER_TVAL, wm, reset_state, reset_cnt); > > +} > > + > > +static void test_basic_functionality(void) > > +{ > > + int32_t tval = (int32_t)msec_to_cycles(10); > > + uint64_t cval; > > + int i; > > + > > + for_each_wfi_method(i) { > > + wfi_method_t wm = wfi_method[i]; > > + > > + cval = DEF_CNT + msec_to_cycles(10); > > + > > + test_timer_cval(cval, wm, true, DEF_CNT); > > + test_timer_tval(tval, wm, true, DEF_CNT); > > + } > > +} > > + > > +/* > > + * This test checks basic timer behavior without actually firing timers, things > > + * like: the relationship between cval and tval, tval down-counting. > > + */ > > +static void timers_sanity_checks(bool use_sched) > > +{ > > + reset_timer_state(DEF_CNT); > > + > > + local_irq_disable(); > > + > > + /* cval in the past */ > > + TIMER_SET_CVAL(TIMER_GET_CNTCT() - msec_to_cycles(10)); > > + if (use_sched) > > + USERSPACE_SCHEDULE(); > > + GUEST_ASSERT(TIMER_GET_TVAL() < 0); > > + > > + /* tval in the past */ > > + TIMER_SET_TVAL(-1); > > + if (use_sched) > > + USERSPACE_SCHEDULE(); > > + GUEST_ASSERT(TIMER_GET_CVAL() < TIMER_GET_CNTCT()); > > + > > + /* tval larger than TVAL_MAX. */ > > + TIMER_SET_CVAL(TIMER_GET_CNTCT() + TVAL_MAX + msec_to_cycles(10)); > > + if (use_sched) > > + USERSPACE_SCHEDULE(); > > + GUEST_ASSERT(TIMER_GET_TVAL() <= 0); > > + > > + /* > > + * tval larger than 2 * TVAL_MAX. > > + * Twice the TVAL_MAX completely loops around the TVAL. > > + */ > > + TIMER_SET_CVAL(TIMER_GET_CNTCT() + 2ULL * TVAL_MAX + msec_to_cycles(10)); > > + if (use_sched) > > + USERSPACE_SCHEDULE(); > > + GUEST_ASSERT_1(TIMER_GET_TVAL() <= msec_to_cycles(10), TIMER_GET_TVAL()); > > + > > + /* negative tval that rollovers from 0. */ > > + SET_COUNTER(msec_to_cycles(1)); > > + TIMER_SET_TVAL(-1 * msec_to_cycles(10)); > > + if (use_sched) > > + USERSPACE_SCHEDULE(); > > + GUEST_ASSERT(TIMER_GET_CVAL() >= (CVAL_MAX - msec_to_cycles(9))); > > + > > + /* tval should keep down-counting from 0 to -1. */ > > + TIMER_SET_TVAL(0); > > + /* We just need 1 cycle to pass. */ > > + isb(); > > + GUEST_ASSERT(TIMER_GET_TVAL() < 0); > > + > > + local_irq_enable(); > > + > > + /* Mask and disable any pending timer. */ > > + TIMER_SET_CTL(CTL_IMASK); > > +} > > There are instances of not-so-sane Generic Timers, such as the XGene-1 > that probably won't be fun to test. Marc would know more about this, but > there may need to be a denylist of bad implementations. > Actually, QEMU-TCG fails some tests (related to rollovers). I had a commmit to add a cmdline arg to not run those. I decided in favor of failing in those cases as well. > > +static void test_timers_sanity_checks(void) > > +{ > > + timers_sanity_checks(false); > > + /* Check how KVM saves/restores these edge-case values. */ > > + timers_sanity_checks(true); > > +} > > + > > +static void guest_run_iteration(void) > > +{ > > + test_basic_functionality(); > > + test_timers_sanity_checks(); > > +} > > + > > +static void guest_code(void) > > +{ > > + int i; > > + > > + local_irq_disable(); > > + > > + gic_init(GIC_V3, 1, (void *)GICD_BASE_GPA, (void *)GICR_BASE_GPA); > > + > > + TIMER_SET_CTL(CTL_IMASK); > > + timer_set_ctl(PHYSICAL, CTL_IMASK); > > + > > + gic_irq_enable(vtimer_irq); > > + gic_irq_enable(ptimer_irq); > > + local_irq_enable(); > > + > > + for (i = 0; i < test_args.iterations; i++) { > > + GUEST_SYNC(i); > > + guest_run_iteration(); > > + } > > + > > + GUEST_DONE(); > > +} > > + > > +static void migrate_self(uint32_t new_pcpu) > > +{ > > + int ret; > > + cpu_set_t cpuset; > > + pthread_t thread; > > + > > + thread = pthread_self(); > > + > > + CPU_ZERO(&cpuset); > > + CPU_SET(new_pcpu, &cpuset); > > + > > + pr_debug("Migrating from %u to %u\n", sched_getcpu(), new_pcpu); > > + > > + ret = pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset); > > + > > + TEST_ASSERT(ret == 0, "Failed to migrate to pCPU: %u; ret: %d\n", > > + new_pcpu, ret); > > +} > > + > > +/* > > + * Set the two pcpus that the test will use to alternate between. Default to > > + * use the current cpu as pcpus[0] and the one right after in the affinity set > > + * as pcpus[1]. > > + */ > > +static void set_default_pcpus(void) > > +{ > > + int max = get_nprocs(); > > + int curr = sched_getcpu(); > > + cpu_set_t cpuset; > > + long i; > > + > > + TEST_ASSERT(max > 1, "Need at least 2 online pcpus."); > > Should the test skip (instead of fail) on such a precondition? > Yes, that would be nicer, will add the check in v2. > > + pcpus[0] = curr; > > + > > + sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpuset); > > + for (i = (curr + 1) % CPU_SETSIZE; i != curr; i = (i + 1) % CPU_SETSIZE) { > > + if (CPU_ISSET(i, &cpuset)) { > > + pcpus[1] = i; > > + break; > > + } > > + } > > + > > + TEST_ASSERT(pcpus[1] != -1, "Couldn't find a second pcpu."); > > + pr_debug("pcpus: %d %d\n", pcpus[0], pcpus[1]); > > +} > > + > > +static void kvm_set_cntxct(struct kvm_vm *vm, uint64_t cnt, enum arch_timer timer) > > +{ > > + TEST_ASSERT(timer == VIRTUAL, > > + "Only supports setting the virtual counter for now."); > > + > > + struct kvm_one_reg reg = { > > + .id = KVM_REG_ARM_TIMER_CNT, > > + .addr = (uint64_t)&cnt, > > + }; > > + vcpu_set_reg(vm, 0, ®); > > +} > > + > > +static void handle_sync(struct kvm_vm *vm, struct ucall *uc) > > +{ > > + sync_cmd_t cmd = uc->args[1]; > > + uint64_t val = uc->args[2]; > > + enum arch_timer timer = uc->args[3]; > > + > > + switch (cmd) { > > + case SET_REG_KVM_REG_ARM_TIMER_CNT: > > + kvm_set_cntxct(vm, val, timer); > > + break; > > + case USERSPACE_SCHED_YIELD: > > + sched_yield(); > > + break; > > + case USERSPACE_MIGRATE_SELF: > > + migrate_self(next_pcpu()); > > + break; > > + default: > > + break; > > + } > > +} > > + > > +static void test_run(struct kvm_vm *vm) > > +{ > > + struct ucall uc; > > + int stage = 0; > > + > > + /* Start on the first pcpu. */ > > + migrate_self(pcpus[0]); > > + > > + sync_global_to_guest(vm, test_args); > > + > > + for (stage = 0; ; stage++) { > > + vcpu_run(vm, VCPUID); > > + switch (get_ucall(vm, VCPUID, &uc)) { > > + case UCALL_SYNC: > > + handle_sync(vm, &uc); > > + break; > > + case UCALL_DONE: > > + goto out; > > + case UCALL_ABORT: > > + TEST_FAIL("%s at %s:%ld\n\tvalues: %lu, %lu; %lu", > > + (const char *)uc.args[0], __FILE__, uc.args[1], > > + uc.args[2], uc.args[3], uc.args[4]); > > + goto out; > > + default: > > + TEST_FAIL("Unexpected guest exit\n"); > > + } > > + } > > + > > +out: > > + return; > > +} > > + > > +static void test_init_timer_irq(struct kvm_vm *vm) > > +{ > > + int vcpu_fd = vcpu_get_fd(vm, VCPUID); > > + > > + kvm_device_access(vcpu_fd, KVM_ARM_VCPU_TIMER_CTRL, > > + KVM_ARM_VCPU_TIMER_IRQ_PTIMER, &ptimer_irq, false); > > + kvm_device_access(vcpu_fd, KVM_ARM_VCPU_TIMER_CTRL, > > + KVM_ARM_VCPU_TIMER_IRQ_VTIMER, &vtimer_irq, false); > > + > > + sync_global_to_guest(vm, ptimer_irq); > > + sync_global_to_guest(vm, vtimer_irq); > > + > > + pr_debug("ptimer_irq: %d; vtimer_irq: %d\n", ptimer_irq, vtimer_irq); > > +} > > + > > +static struct kvm_vm *test_vm_create(void) > > +{ > > + struct kvm_vm *vm; > > + > > + vm = vm_create_default(VCPUID, 0, guest_code); > > + > > + vm_init_descriptor_tables(vm); > > + vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, guest_irq_handler); > > + > > + vcpu_init_descriptor_tables(vm, 0); > > + > > + ucall_init(vm, NULL); > > + test_init_timer_irq(vm); > > + vgic_v3_setup(vm, 1, 64, GICD_BASE_GPA, GICR_BASE_GPA); > > The test should probably skip if GICv3 isn't supported, like commit 456f89e0928a > ("KVM: selftests: aarch64: Skip tests if we can't create a vgic-v3") > Ack, will add the check in v2. > > + return vm; > > +} > > + > > +static void test_print_help(char *name) > > +{ > > + pr_info("Usage: %s [-h] [-i iterations] [-w] [-p pcpu1,pcpu2]\n", > > + name); > > + pr_info("\t-i: Number of iterations (default: %u)\n", > > + NR_TEST_ITERS_DEF); > > + pr_info("\t-p: Pair of pcpus for the vcpus to alternate between. " > > + "Defaults to use the current cpu and the one right after " > > + "in the affinity set.\n"); > > + pr_info("\t-h: Print this help message\n"); > > +} > > + > > +static bool parse_args(int argc, char *argv[]) > > +{ > > + int opt, ret; > > + > > + while ((opt = getopt(argc, argv, "hi:p:")) != -1) { > > + switch (opt) { > > + case 'i': > > + test_args.iterations = atoi(optarg); > > + if (test_args.iterations <= 0) { > > + pr_info("Positive value needed for -i\n"); > > + goto err; > > + } > > + break; > > + case 'p': > > + ret = sscanf(optarg, "%u,%u", &pcpus[0], &pcpus[1]); > > + if (ret != 2) { > > + pr_info("Invalid pcpus pair"); > > + goto err; > > + } > > + break; > > + case 'h': > > + default: > > + goto err; > > + } > > + } > > + > > + return true; > > + > > +err: > > + test_print_help(argv[0]); > > + return false; > > +} > > + > > +int main(int argc, char *argv[]) > > +{ > > + struct kvm_vm *vm; > > + > > + /* Tell stdout not to buffer its content */ > > + setbuf(stdout, NULL); > > + > > + if (!parse_args(argc, argv)) > > + exit(KSFT_SKIP); > > + > > + if (pcpus[0] == -1 || pcpus[1] == -1) > > + set_default_pcpus(); > > + > > + vm = test_vm_create(); > > + test_run(vm); > > + kvm_vm_free(vm); > > + > > + return 0; > > +} > > -- > > 2.35.1.574.g5d30c73bfb-goog > Thanks for the review! Will work on v2.