From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chao Du Date: Wed, 27 Mar 2024 18:17:03 +0800 (GMT+08:00) Subject: [PATCH v3 3/3] RISC-V: KVM: selftests: Add ebreak test support In-Reply-To: <20240327-b867e01dab2996d68c15f899@orel> References: <20240327075526.31855-1-duchao@eswincomputing.com> <20240327075526.31855-4-duchao@eswincomputing.com> <20240327-b867e01dab2996d68c15f899@orel> Message-ID: <4bc71b14.1591.18e7f69c9e3.Coremail.duchao@eswincomputing.com> List-Id: To: kvm-riscv@lists.infradead.org MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Thanks Andrew for all the good suggestions. Will take them in next revision. Regards, Chao On 2024-03-27 17:00, Andrew Jones wrote: > > On Wed, Mar 27, 2024 at 07:55:26AM +0000, Chao Du wrote: > > Initial support for RISC-V KVM ebreak test. Check the exit reason and > > the PC when guest debug is enabled. Also to make sure the guest could > > handle the ebreak exception without exiting to the VMM when guest debug > > is not enabled. > > > > Signed-off-by: Chao Du > > --- > > tools/testing/selftests/kvm/Makefile | 1 + > > .../testing/selftests/kvm/riscv/ebreak_test.c | 84 +++++++++++++++++++ > > 2 files changed, 85 insertions(+) > > create mode 100644 tools/testing/selftests/kvm/riscv/ebreak_test.c > > > > diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile > > index 741c7dc16afc..7f4430242c9e 100644 > > --- a/tools/testing/selftests/kvm/Makefile > > +++ b/tools/testing/selftests/kvm/Makefile > > @@ -189,6 +189,7 @@ TEST_GEN_PROGS_s390x += rseq_test > > TEST_GEN_PROGS_s390x += set_memory_region_test > > TEST_GEN_PROGS_s390x += kvm_binary_stats_test > > > > +TEST_GEN_PROGS_riscv += riscv/ebreak_test > > TEST_GEN_PROGS_riscv += arch_timer > > TEST_GEN_PROGS_riscv += demand_paging_test > > TEST_GEN_PROGS_riscv += dirty_log_test > > diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c > > new file mode 100644 > > index 000000000000..4c79c778e026 > > --- /dev/null > > +++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c > > @@ -0,0 +1,84 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * RISC-V KVM ebreak test. > > + * > > + * Copyright 2024 Beijing ESWIN Computing Technology Co., Ltd. > > + * > > + */ > > +#include "kvm_util.h" > > + > > +#define PC(v) ((uint64_t)&(v)) > > PC() isn't a good name for the function this is doing. It's getting > the address of a label. LABEL_ADDRESS() would be more appropriate. > > > + > > +extern unsigned char sw_bp_1, sw_bp_2; > > +static volatile uint64_t sw_bp_addr; > > Drop volatile here and use READ/WRITE_ONCE on sw_bp_addr when reading and > writing it. > > > + > > +static void guest_code(void) > > +{ > > + /* > > + * nops are inserted to make sure that the "pc += 4" operation is > > + * compatible with the compressed instructions. > > + */ > > + asm volatile("sw_bp_1: ebreak\n" > > + "nop\n" > > + "sw_bp_2: ebreak\n" > > + "nop\n"); > > The nops are fine, but options should work too, something like > > asm volatile( > ".option push\n" > ".option norvc\n" > "sw_bp_1: ebreak\n" > "sw_bp_2: ebreak\n" > ".option pop\n" > ); > > > + GUEST_ASSERT_EQ(sw_bp_addr, PC(sw_bp_2)); > > + > > + GUEST_DONE(); > > +} > > + > > +static void guest_breakpoint_handler(struct ex_regs *regs) > > +{ > > + sw_bp_addr = regs->epc; > > + regs->epc += 4; > > +} > > + > > +int main(void) > > +{ > > + struct kvm_vm *vm; > > + struct kvm_vcpu *vcpu; > > + uint64_t pc; > > + struct kvm_guest_debug debug = { > > + .control = KVM_GUESTDBG_ENABLE, > > + }; > > + struct ucall uc; > > You don't use 'uc', so you can drop it and... > > > + > > + TEST_REQUIRE(kvm_has_cap(KVM_CAP_SET_GUEST_DEBUG)); > > + > > + vm = vm_create_with_one_vcpu(&vcpu, guest_code); > > + > > + vm_init_vector_tables(vm); > > + vcpu_init_vector_tables(vcpu); > > + vm_install_exception_handler(vm, EXC_BREAKPOINT, > > + guest_breakpoint_handler); > > + > > + /* > > + * Enable the guest debug. > > + * ebreak should exit to the VMM with KVM_EXIT_DEBUG reason. > > + */ > > + vcpu_guest_debug_set(vcpu, &debug); > > + vcpu_run(vcpu); > > + > > + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_DEBUG); > > + > > + vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &pc); > > + TEST_ASSERT_EQ(pc, PC(sw_bp_1)); > > + > > + /* skip sw_bp_1 */ > > + vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.pc), pc + 4); > > + > > + /* > > + * Disable all debug controls. > > + * Guest should handle the ebreak without exiting to the VMM. > > + */ > > + memset(&debug, 0, sizeof(debug)); > > + vcpu_guest_debug_set(vcpu, &debug); > > + > > + vcpu_run(vcpu); > > + > > + TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_DONE); > > ...call get_ucall() with NULL for the second parameter. > > > + > > + kvm_vm_free(vm); > > + > > + return 0; > > +} > > -- > > 2.17.1 > > > > Thanks, > drew From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tmja5ljk3lje4ms43mwaa.icoremail.net (zg8tmja5ljk3lje4ms43mwaa.icoremail.net [209.97.181.73]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 746924A990 for ; Wed, 27 Mar 2024 10:18:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.97.181.73 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711534706; cv=none; b=vBNbboSe/ZJs7FTAUqtV7QJpLBskBKXfmFaP5Nyc9kwVSR7ltNLcGHt9tfjD6zuvoNu49a6kpQFZ67jyo++XySYyVzU9N1zlcK7S8UJKML1UoajheJD1a0Jx8VvFi2ziUfyTm9n/4iSIbE9ba3fQc+1b5dOMhgGMui23/2USQ78= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711534706; c=relaxed/simple; bh=dawK8vmOlmL5GJc5FUbUbmoh7mab214Ej53yfTxwCRk=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=SbhhOfG1C5uelDTfnETznLKmLsPPTS8ruq6awHuCqYp7kg5z9aSo+vcGZswXiA1ZcYUXEuoOyS+cpUXIYcr23SF2csj3Dw1Hm7fIKg90Ba7Fwxu9fu/uOF3nfTAYWFCwXXtr4b/Li9EMrD8Gl8lJ6iMA9Y5wH2cyZvG3YBtGr9A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com; spf=pass smtp.mailfrom=eswincomputing.com; arc=none smtp.client-ip=209.97.181.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from duchao$eswincomputing.com ( [10.64.113.11] ) by ajax-webmail-app2 (Coremail) ; Wed, 27 Mar 2024 18:17:03 +0800 (GMT+08:00) Date: Wed, 27 Mar 2024 18:17:03 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Chao Du" To: "Andrew Jones" Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, anup@brainfault.org, atishp@atishpatra.org, pbonzini@redhat.com, shuah@kernel.org, dbarboza@ventanamicro.com, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, haibo1.xu@intel.com, duchao713@qq.com Subject: Re: [PATCH v3 3/3] RISC-V: KVM: selftests: Add ebreak test support X-Priority: 3 X-Mailer: Coremail Webmail Server Version XT6.0.3 build 20220420(169d3f8c) Copyright (c) 2002-2024 www.mailtech.cn mispb-72143050-eaf5-4703-89e0-86624513b4ce-eswincomputing.com In-Reply-To: <20240327-b867e01dab2996d68c15f899@orel> References: <20240327075526.31855-1-duchao@eswincomputing.com> <20240327075526.31855-4-duchao@eswincomputing.com> <20240327-b867e01dab2996d68c15f899@orel> Content-Transfer-Encoding: base64 Content-Type: text/plain; charset=UTF-8 Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <4bc71b14.1591.18e7f69c9e3.Coremail.duchao@eswincomputing.com> X-Coremail-Locale: en_US X-CM-TRANSID:TQJkCgBHWbsf8gNmwRIDAA--.1629W X-CM-SenderInfo: xgxfxt3r6h245lqf0zpsxwx03jof0z/1tbiAQEJDGYD58QCNgAAs3 X-Coremail-Antispam: 1Ur529EdanIXcx71UUUUU7IcSsGvfJ3iIAIbVAYjsxI4VWxJw CS07vEb4IE77IF4wCS07vE1I0E4x80FVAKz4kxMIAIbVAFxVCaYxvI4VCIwcAKzIAtYxBI daVFxhVjvjDU= VGhhbmtzIEFuZHJldyBmb3IgYWxsIHRoZSBnb29kIHN1Z2dlc3Rpb25zLgpXaWxsIHRha2UgdGhl bSBpbiBuZXh0IHJldmlzaW9uLgoKUmVnYXJkcywKQ2hhbwoKT24gMjAyNC0wMy0yNyAxNzowMCwg QW5kcmV3IEpvbmVzIDxham9uZXNAdmVudGFuYW1pY3JvLmNvbT4gd3JvdGU6Cj4gCj4gT24gV2Vk LCBNYXIgMjcsIDIwMjQgYXQgMDc6NTU6MjZBTSArMDAwMCwgQ2hhbyBEdSB3cm90ZToKPiA+IElu aXRpYWwgc3VwcG9ydCBmb3IgUklTQy1WIEtWTSBlYnJlYWsgdGVzdC4gQ2hlY2sgdGhlIGV4aXQg cmVhc29uIGFuZAo+ID4gdGhlIFBDIHdoZW4gZ3Vlc3QgZGVidWcgaXMgZW5hYmxlZC4gQWxzbyB0 byBtYWtlIHN1cmUgdGhlIGd1ZXN0IGNvdWxkCj4gPiBoYW5kbGUgdGhlIGVicmVhayBleGNlcHRp b24gd2l0aG91dCBleGl0aW5nIHRvIHRoZSBWTU0gd2hlbiBndWVzdCBkZWJ1Zwo+ID4gaXMgbm90 IGVuYWJsZWQuCj4gPiAKPiA+IFNpZ25lZC1vZmYtYnk6IENoYW8gRHUgPGR1Y2hhb0Blc3dpbmNv bXB1dGluZy5jb20+Cj4gPiAtLS0KPiA+ICB0b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9rdm0vTWFr ZWZpbGUgICAgICAgICAgfCAgMSArCj4gPiAgLi4uL3Rlc3Rpbmcvc2VsZnRlc3RzL2t2bS9yaXNj di9lYnJlYWtfdGVzdC5jIHwgODQgKysrKysrKysrKysrKysrKysrKwo+ID4gIDIgZmlsZXMgY2hh bmdlZCwgODUgaW5zZXJ0aW9ucygrKQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCB0b29scy90ZXN0 aW5nL3NlbGZ0ZXN0cy9rdm0vcmlzY3YvZWJyZWFrX3Rlc3QuYwo+ID4gCj4gPiBkaWZmIC0tZ2l0 IGEvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtL01ha2VmaWxlIGIvdG9vbHMvdGVzdGluZy9z ZWxmdGVzdHMva3ZtL01ha2VmaWxlCj4gPiBpbmRleCA3NDFjN2RjMTZhZmMuLjdmNDQzMDI0MmM5 ZSAxMDA2NDQKPiA+IC0tLSBhL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2t2bS9NYWtlZmlsZQo+ ID4gKysrIGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtL01ha2VmaWxlCj4gPiBAQCAtMTg5 LDYgKzE4OSw3IEBAIFRFU1RfR0VOX1BST0dTX3MzOTB4ICs9IHJzZXFfdGVzdAo+ID4gIFRFU1Rf R0VOX1BST0dTX3MzOTB4ICs9IHNldF9tZW1vcnlfcmVnaW9uX3Rlc3QKPiA+ICBURVNUX0dFTl9Q Uk9HU19zMzkweCArPSBrdm1fYmluYXJ5X3N0YXRzX3Rlc3QKPiA+ICAKPiA+ICtURVNUX0dFTl9Q Uk9HU19yaXNjdiArPSByaXNjdi9lYnJlYWtfdGVzdAo+ID4gIFRFU1RfR0VOX1BST0dTX3Jpc2N2 ICs9IGFyY2hfdGltZXIKPiA+ICBURVNUX0dFTl9QUk9HU19yaXNjdiArPSBkZW1hbmRfcGFnaW5n X3Rlc3QKPiA+ICBURVNUX0dFTl9QUk9HU19yaXNjdiArPSBkaXJ0eV9sb2dfdGVzdAo+ID4gZGlm ZiAtLWdpdCBhL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL2t2bS9yaXNjdi9lYnJlYWtfdGVzdC5j IGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtL3Jpc2N2L2VicmVha190ZXN0LmMKPiA+IG5l dyBmaWxlIG1vZGUgMTAwNjQ0Cj4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLjRjNzljNzc4ZTAyNgo+ ID4gLS0tIC9kZXYvbnVsbAo+ID4gKysrIGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMva3ZtL3Jp c2N2L2VicmVha190ZXN0LmMKPiA+IEBAIC0wLDAgKzEsODQgQEAKPiA+ICsvLyBTUERYLUxpY2Vu c2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ID4gKy8qCj4gPiArICogUklTQy1WIEtWTSBlYnJlYWsg dGVzdC4KPiA+ICsgKgo+ID4gKyAqIENvcHlyaWdodCAyMDI0IEJlaWppbmcgRVNXSU4gQ29tcHV0 aW5nIFRlY2hub2xvZ3kgQ28uLCBMdGQuCj4gPiArICoKPiA+ICsgKi8KPiA+ICsjaW5jbHVkZSAi a3ZtX3V0aWwuaCIKPiA+ICsKPiA+ICsjZGVmaW5lIFBDKHYpICgodWludDY0X3QpJih2KSkKPiAK PiBQQygpIGlzbid0IGEgZ29vZCBuYW1lIGZvciB0aGUgZnVuY3Rpb24gdGhpcyBpcyBkb2luZy4g SXQncyBnZXR0aW5nCj4gdGhlIGFkZHJlc3Mgb2YgYSBsYWJlbC4gTEFCRUxfQUREUkVTUygpIHdv dWxkIGJlIG1vcmUgYXBwcm9wcmlhdGUuCj4gCj4gPiArCj4gPiArZXh0ZXJuIHVuc2lnbmVkIGNo YXIgc3dfYnBfMSwgc3dfYnBfMjsKPiA+ICtzdGF0aWMgdm9sYXRpbGUgdWludDY0X3Qgc3dfYnBf YWRkcjsKPiAKPiBEcm9wIHZvbGF0aWxlIGhlcmUgYW5kIHVzZSBSRUFEL1dSSVRFX09OQ0Ugb24g c3dfYnBfYWRkciB3aGVuIHJlYWRpbmcgYW5kCj4gd3JpdGluZyBpdC4KPiAKPiA+ICsKPiA+ICtz dGF0aWMgdm9pZCBndWVzdF9jb2RlKHZvaWQpCj4gPiArewo+ID4gKwkvKgo+ID4gKwkgKiBub3Bz IGFyZSBpbnNlcnRlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgInBjICs9IDQiIG9wZXJhdGlvbiBp cwo+ID4gKwkgKiBjb21wYXRpYmxlIHdpdGggdGhlIGNvbXByZXNzZWQgaW5zdHJ1Y3Rpb25zLgo+ ID4gKwkgKi8KPiA+ICsJYXNtIHZvbGF0aWxlKCJzd19icF8xOiBlYnJlYWtcbiIKPiA+ICsJCSAg ICAgIm5vcFxuIgo+ID4gKwkJICAgICAic3dfYnBfMjogZWJyZWFrXG4iCj4gPiArCQkgICAgICJu b3BcbiIpOwo+IAo+IFRoZSBub3BzIGFyZSBmaW5lLCBidXQgb3B0aW9ucyBzaG91bGQgd29yayB0 b28sIHNvbWV0aGluZyBsaWtlCj4gCj4gIGFzbSB2b2xhdGlsZSgKPiAgIi5vcHRpb24gcHVzaFxu Igo+ICAiLm9wdGlvbiBub3J2Y1xuIgo+ICAic3dfYnBfMTogZWJyZWFrXG4iCj4gICJzd19icF8y OiBlYnJlYWtcbiIKPiAgIi5vcHRpb24gcG9wXG4iCj4gICk7Cj4gCj4gPiArCUdVRVNUX0FTU0VS VF9FUShzd19icF9hZGRyLCBQQyhzd19icF8yKSk7Cj4gPiArCj4gPiArCUdVRVNUX0RPTkUoKTsK PiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgZ3Vlc3RfYnJlYWtwb2ludF9oYW5kbGVyKHN0 cnVjdCBleF9yZWdzICpyZWdzKQo+ID4gK3sKPiA+ICsJc3dfYnBfYWRkciA9IHJlZ3MtPmVwYzsK PiA+ICsJcmVncy0+ZXBjICs9IDQ7Cj4gPiArfQo+ID4gKwo+ID4gK2ludCBtYWluKHZvaWQpCj4g PiArewo+ID4gKwlzdHJ1Y3Qga3ZtX3ZtICp2bTsKPiA+ICsJc3RydWN0IGt2bV92Y3B1ICp2Y3B1 Owo+ID4gKwl1aW50NjRfdCBwYzsKPiA+ICsJc3RydWN0IGt2bV9ndWVzdF9kZWJ1ZyBkZWJ1ZyA9 IHsKPiA+ICsJCS5jb250cm9sID0gS1ZNX0dVRVNUREJHX0VOQUJMRSwKPiA+ICsJfTsKPiA+ICsJ c3RydWN0IHVjYWxsIHVjOwo+IAo+IFlvdSBkb24ndCB1c2UgJ3VjJywgc28geW91IGNhbiBkcm9w IGl0IGFuZC4uLgo+IAo+ID4gKwo+ID4gKwlURVNUX1JFUVVJUkUoa3ZtX2hhc19jYXAoS1ZNX0NB UF9TRVRfR1VFU1RfREVCVUcpKTsKPiA+ICsKPiA+ICsJdm0gPSB2bV9jcmVhdGVfd2l0aF9vbmVf dmNwdSgmdmNwdSwgZ3Vlc3RfY29kZSk7Cj4gPiArCj4gPiArCXZtX2luaXRfdmVjdG9yX3RhYmxl cyh2bSk7Cj4gPiArCXZjcHVfaW5pdF92ZWN0b3JfdGFibGVzKHZjcHUpOwo+ID4gKwl2bV9pbnN0 YWxsX2V4Y2VwdGlvbl9oYW5kbGVyKHZtLCBFWENfQlJFQUtQT0lOVCwKPiA+ICsJCQkJCWd1ZXN0 X2JyZWFrcG9pbnRfaGFuZGxlcik7Cj4gPiArCj4gPiArCS8qCj4gPiArCSAqIEVuYWJsZSB0aGUg Z3Vlc3QgZGVidWcuCj4gPiArCSAqIGVicmVhayBzaG91bGQgZXhpdCB0byB0aGUgVk1NIHdpdGgg S1ZNX0VYSVRfREVCVUcgcmVhc29uLgo+ID4gKwkgKi8KPiA+ICsJdmNwdV9ndWVzdF9kZWJ1Z19z ZXQodmNwdSwgJmRlYnVnKTsKPiA+ICsJdmNwdV9ydW4odmNwdSk7Cj4gPiArCj4gPiArCVRFU1Rf QVNTRVJUX0tWTV9FWElUX1JFQVNPTih2Y3B1LCBLVk1fRVhJVF9ERUJVRyk7Cj4gPiArCj4gPiAr CXZjcHVfZ2V0X3JlZyh2Y3B1LCBSSVNDVl9DT1JFX1JFRyhyZWdzLnBjKSwgJnBjKTsKPiA+ICsJ VEVTVF9BU1NFUlRfRVEocGMsIFBDKHN3X2JwXzEpKTsKPiA+ICsKPiA+ICsJLyogc2tpcCBzd19i cF8xICovCj4gPiArCXZjcHVfc2V0X3JlZyh2Y3B1LCBSSVNDVl9DT1JFX1JFRyhyZWdzLnBjKSwg cGMgKyA0KTsKPiA+ICsKPiA+ICsJLyoKPiA+ICsJICogRGlzYWJsZSBhbGwgZGVidWcgY29udHJv bHMuCj4gPiArCSAqIEd1ZXN0IHNob3VsZCBoYW5kbGUgdGhlIGVicmVhayB3aXRob3V0IGV4aXRp bmcgdG8gdGhlIFZNTS4KPiA+ICsJICovCj4gPiArCW1lbXNldCgmZGVidWcsIDAsIHNpemVvZihk ZWJ1ZykpOwo+ID4gKwl2Y3B1X2d1ZXN0X2RlYnVnX3NldCh2Y3B1LCAmZGVidWcpOwo+ID4gKwo+ ID4gKwl2Y3B1X3J1bih2Y3B1KTsKPiA+ICsKPiA+ICsJVEVTVF9BU1NFUlRfRVEoZ2V0X3VjYWxs KHZjcHUsICZ1YyksIFVDQUxMX0RPTkUpOwo+IAo+IC4uLmNhbGwgZ2V0X3VjYWxsKCkgd2l0aCBO VUxMIGZvciB0aGUgc2Vjb25kIHBhcmFtZXRlci4KPiAKPiA+ICsKPiA+ICsJa3ZtX3ZtX2ZyZWUo dm0pOwo+ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiAtLSAKPiA+IDIuMTcuMQo+ID4K PiAKPiBUaGFua3MsCj4gZHJldwo=