From 19742e6a355d9a1c097a1be7e61144b24dcb9062 Mon Sep 17 00:00:00 2001 From: Thomas Stokes Date: Fri, 27 Dec 2024 01:19:51 +0800 Subject: [PATCH] not better --- arch/wasm/kernel/irq.c | 4 +- block/bdev.c | 2 +- drivers/block/virtio_blk.c | 1 - drivers/virtio/virtio_ring.c | 3 +- tools/wasm/Makefile | 2 +- tools/wasm/src/disk.img | 1 + tools/wasm/src/env.d.ts | 2 +- tools/wasm/src/index.ts | 2 + tools/wasm/src/root.squashfs | Bin 4096 -> 0 bytes tools/wasm/src/virtio.ts | 118 +++++++++++++++++++---------------- 10 files changed, 73 insertions(+), 62 deletions(-) create mode 120000 tools/wasm/src/disk.img delete mode 100644 tools/wasm/src/root.squashfs diff --git a/arch/wasm/kernel/irq.c b/arch/wasm/kernel/irq.c index bfbfa334b4e05b..755be8203becb3 100644 --- a/arch/wasm/kernel/irq.c +++ b/arch/wasm/kernel/irq.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) "wasm/irq: " fmt - #include #include #include @@ -82,7 +80,7 @@ void arch_local_irq_restore(unsigned long flags) static int wasm_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - pr_info("wasm_irq_map: %d -> %lu\n", irq, hw); + pr_info("map irq: %d -> %lu\n", irq, hw); irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_percpu_irq); diff --git a/block/bdev.c b/block/bdev.c index 3d7c45fbef6fd2..5cf0fef371ec8e 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -998,7 +998,7 @@ int lookup_bdev(const char *pathname, dev_t *dev) if (!may_open_dev(&path)) goto out_path_put; - pr_info("rdev: %p %d\n", inode, inode->i_rdev); + pr_info("rdev: %p %d %x\n", inode, inode->i_rdev, inode->i_mode); *dev = inode->i_rdev; error = 0; out_path_put: diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index efa5535a8e1d87..78cd13b7e285a4 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0-only -//#define DEBUG #include #include #include diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 4c102a39c05c63..efd447f1cfff0b 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3,6 +3,7 @@ * * Copyright 2007 Rusty Russell IBM Corporation */ +#define DEBUG #define pr_fmt(fmt) "vring: " fmt #include @@ -1386,7 +1387,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, err = virtqueue_add_indirect_packed(vq, sgs, total_sg, out_sgs, in_sgs, data, gfp); if (err != -ENOMEM) { - END_USE(vq); + // END_USE(vq); return err; } diff --git a/tools/wasm/Makefile b/tools/wasm/Makefile index 91e10e319e0ea2..fcbe2903cb9953 100644 --- a/tools/wasm/Makefile +++ b/tools/wasm/Makefile @@ -18,7 +18,7 @@ _kernel: $(Q)$(MAKE) -C ../.. tools/wasm/src/build/vmlinux.wasm tools/wasm/src/build/sections.json dist/index.js: _kernel $(shell find src -type f) - $(Q)$(ESBUILD) --bundle src/index.ts --outdir=dist --format=esm --splitting --sourcemap --loader:.wasm=file --loader:.squashfs=file + $(Q)$(ESBUILD) --bundle src/index.ts --outdir=dist --format=esm --splitting --sourcemap --loader:.wasm=file --loader:.img=file dist/index.d.ts: _kernel $(shell find src -type f -name '*.ts') $(Q)$(TSC) diff --git a/tools/wasm/src/disk.img b/tools/wasm/src/disk.img new file mode 120000 index 00000000000000..1d790bc654ed4e --- /dev/null +++ b/tools/wasm/src/disk.img @@ -0,0 +1 @@ +/home/tom/tmp/linuxwasm/disk.img \ No newline at end of file diff --git a/tools/wasm/src/env.d.ts b/tools/wasm/src/env.d.ts index 1d22e1960711f4..6a665705c7b1e6 100644 --- a/tools/wasm/src/env.d.ts +++ b/tools/wasm/src/env.d.ts @@ -3,7 +3,7 @@ declare module "*.wasm" { export default url; } -declare module "*.squashfs" { +declare module "*.img" { const url: string; export default url; } diff --git a/tools/wasm/src/index.ts b/tools/wasm/src/index.ts index db3e41a254c6e9..48b59d7e13a51c 100644 --- a/tools/wasm/src/index.ts +++ b/tools/wasm/src/index.ts @@ -162,6 +162,8 @@ export class Machine extends EventEmitter<{ const instance = (await WebAssembly.instantiate(vmlinux, imports)) as Instance; + // @ts-expect-error + globalThis.instance = instance; instance.exports.boot(); } } diff --git a/tools/wasm/src/root.squashfs b/tools/wasm/src/root.squashfs deleted file mode 100644 index a6acb9937b4dcc4b8b70536af6996263d6c24f34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmc~OE-YqY0D@)bgcul@Kr99p20?}ZCPpC5zz_izVPKG9gfK*)^nWNwfXbhP(lBut zox||gyecA!fq^ko>7E(W0jml{MlOauO}|neFqAVG#WFB8@Ef=&OlW2@`;`4+`gbiq z@nt`+2x#7(@?~RZny8*8XZZf9DV|TOj=#>`(0p=_*UJS!n}l~f4Q62Us#x{^}F-At&H9(!g0Cgqq0?1%wU}h-F&o5zV y0E#p4!Bm1cqhK@yMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz5l02mk;mzfZLQ diff --git a/tools/wasm/src/virtio.ts b/tools/wasm/src/virtio.ts index d67f41d0636b41..01ce94c9f33d19 100644 --- a/tools/wasm/src/virtio.ts +++ b/tools/wasm/src/virtio.ts @@ -9,10 +9,10 @@ import { } from "./bytes.ts"; import { assert } from "./util.ts"; import type { Imports } from "./wasm.ts"; -import squashfsUrl from "./root.squashfs"; +import rootfsUrl from "./disk.img"; -const squashfs = new Uint8Array( - await (await fetch(new URL(squashfsUrl, import.meta.url))).arrayBuffer(), +const rootfs = new Uint8Array( + await (await fetch(new URL(rootfsUrl, import.meta.url))).arrayBuffer(), ); const TransportFeatures = { @@ -121,7 +121,7 @@ class Virtqueue { this.desc = FixedArray(VirtqDescriptor, size).get(mem, desc_addr); } - pop() { + #pop() { let i = this.#advance(); if (i === null) return null; const head = i; @@ -157,6 +157,11 @@ class Virtqueue { return chain; } + *[Symbol.iterator]() { + let chain; + while (chain = this.#pop()) yield chain; + } + #advance() { const desc = this.desc[this.avail_idx]; assert(desc); @@ -239,7 +244,7 @@ export class BlockDevice extends VirtioDevice { constructor() { super(); this.features |= BlockDeviceFeatures.FLUSH | BlockDeviceFeatures.RO; - this.config.capacity = BigInt(squashfs.length); + this.config.capacity = BigInt(rootfs.length / 512); } override notify(vq: number) { @@ -248,47 +253,49 @@ export class BlockDevice extends VirtioDevice { const queue = this.vqs[vq]; assert(queue); - const chain = queue.pop(); - assert(chain); - - const [header, data, status, trailing] = chain; - assert(header && !header.writable, "header must be readonly"); - assert( - header.array.byteLength === BlockDeviceRequest.size, - `header size is ${header.array.byteLength}`, - ); - assert(data, "data must exist"); - assert(status && status.writable, "status must be writable"); - assert( - status.array.byteLength === 1, - `status size is ${status.array.byteLength}`, - ); - assert(!trailing, "too many descriptors"); - - const request = new BlockDeviceRequest(header.array); - - let n = 0; - switch (request.type) { - case BlockDeviceRequestType.IN: { - assert(data.writable, "data must be writable when IN"); - const sector = Number(request.sector); - const start = sector * 512; - const end = start + 512; - if (end > squashfs.length) { - status.array[0] = BlockDeviceStatus.IOERR; - } else { - data.array.set(squashfs.slice(start, end)); - n = 512; + for (const chain of queue) { + const [header, data, status, trailing] = chain; + assert(header && !header.writable, "header must be readonly"); + assert( + header.array.byteLength === BlockDeviceRequest.size, + `header size is ${header.array.byteLength}`, + ); + assert(data, "data must exist"); + assert(status && status.writable, "status must be writable"); + assert( + status.array.byteLength === 1, + `status size is ${status.array.byteLength}`, + ); + assert(!trailing, "too many descriptors"); + + const request = new BlockDeviceRequest(header.array); + + let n = 0; + switch (request.type) { + case BlockDeviceRequestType.IN: { + assert(data.writable, "data must be writable when IN"); + const start = Number(request.sector) * 512; + let end = start + data.array.byteLength; + if (end >= rootfs.length) end = rootfs.length - 1; + data.array.set(rootfs.subarray(start, end)); + n = end - start; status.array[0] = BlockDeviceStatus.OK; + break; } - break; + default: + console.error("unknown request type", request.type); + status.array[0] = BlockDeviceStatus.UNSUPP; } - default: - console.error("unknown request type", request.type); - status.array[0] = BlockDeviceStatus.UNSUPP; - } - chain.release(n); + console.log( + request.type, + request.sector, + status.array[0], + btoa(String.fromCharCode(...data.array)), + ); + + chain.release(n); + } this.trigger_interrupt("vring"); } } @@ -304,20 +311,20 @@ export class EntropyDevice extends VirtioDevice { const queue = this.vqs[vq]; assert(queue); - const chain = queue.pop(); - assert(chain); - let n = 0; - for (const { array, writable } of chain) { - assert(writable); + for (const chain of queue) { + let n = 0; + for (const { array, writable } of chain) { + assert(writable); - // can't use crypto.getRandomValues on a SharedArrayBuffer - const arr = new Uint8Array(array.length); - crypto.getRandomValues(arr); - array.set(arr); + // can't use crypto.getRandomValues on a SharedArrayBuffer + const arr = new Uint8Array(array.length); + crypto.getRandomValues(arr); + array.set(arr); - n += array.byteLength; + n += array.byteLength; + } + chain.release(n); } - chain.release(n); this.trigger_interrupt("vring"); } @@ -340,7 +347,10 @@ export function virtio_imports( set_features(dev, features) { const device = devices[dev]; assert(device); - device.features = features; + assert( + device.features === features, + "the kernel should accept every feature we offer, and no more", + ); }, enable_vring(dev, vq, size, desc_addr) {