From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: [PATCH RESEND 05/11] ALSA: vsnd: Implement handling of shared buffers Date: Mon, 7 Aug 2017 14:50:39 +0300 Message-ID: <1502106645-6731-6-git-send-email-andr2000@gmail.com> References: <1502106645-6731-1-git-send-email-andr2000@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1502106645-6731-1-git-send-email-andr2000@gmail.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: alsa-devel@alsa-project.org, xen-devel@lists.xen.org, linux-kernel@vger.kernel.org Cc: andr2000@gmail.com, Oleksandr Andrushchenko , tiwai@suse.com, perex@perex.cz List-Id: alsa-devel@alsa-project.org RnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgoKSW1wbGVtZW50IHNoYXJlZCBidWZmZXIgaGFuZGxpbmcgYWNjb3JkaW5nIHRvIHRo ZQpwYXJhLXZpcnR1YWxpemVkIHNvdW5kIGRldmljZSBwcm90b2NvbCBhdCB4ZW4vaW50ZXJmYWNl L2lvL3NuZGlmLmg6Ci0gbWFuYWdlIGJ1ZmZlciBtZW1vcnkKLSBoYW5kbGUgZ3JhbnRlZCByZWZl cmVuY2VzCi0gaGFuZGxlIHBhZ2UgZGlyZWN0b3JpZXMKClNpZ25lZC1vZmYtYnk6IE9sZWtzYW5k ciBBbmRydXNoY2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5rb0BlcGFtLmNvbT4KLS0tCiBz b3VuZC9kcml2ZXJzL3hlbi1mcm9udC5jIHwgMTc4ICsrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysKIDEgZmlsZSBjaGFuZ2VkLCAxNzggaW5zZXJ0aW9ucygrKQoK ZGlmZiAtLWdpdCBhL3NvdW5kL2RyaXZlcnMveGVuLWZyb250LmMgYi9zb3VuZC9kcml2ZXJzL3hl bi1mcm9udC5jCmluZGV4IGE5MjQ1OWIyNzM3ZS4uMDRlYmMxNTc1N2Y0IDEwMDY0NAotLS0gYS9z b3VuZC9kcml2ZXJzL3hlbi1mcm9udC5jCisrKyBiL3NvdW5kL2RyaXZlcnMveGVuLWZyb250LmMK QEAgLTU4LDYgKzU4LDE0IEBAIHN0cnVjdCB4ZHJ2X2V2dGNobmxfaW5mbyB7CiAJdWludDE2X3Qg cmVzcF9pZDsKIH07CiAKK3N0cnVjdCBzaF9idWZfaW5mbyB7CisJaW50IG51bV9ncmVmczsKKwln cmFudF9yZWZfdCAqZ3JlZnM7CisJdWludDhfdCAqdmRpcmVjdG9yeTsKKwl1aW50OF90ICp2YnVm ZmVyOworCXNpemVfdCB2YnVmZmVyX3N6OworfTsKKwogc3RydWN0IGNmZ19zdHJlYW0gewogCWlu dCB1bmlxdWVfaWQ7CiAJY2hhciAqeGVuc3RvcmVfcGF0aDsKQEAgLTgyNSw2ICs4MzMsMTc2IEBA IHN0YXRpYyB2b2lkIHhkcnZfcmVtb3ZlX2ludGVybmFsKHN0cnVjdCB4ZHJ2X2luZm8gKmRydl9p bmZvKQogCXhkcnZfZXZ0Y2hubF9mcmVlX2FsbChkcnZfaW5mbyk7CiB9CiAKK3N0YXRpYyBpbmxp bmUgZ3JhbnRfcmVmX3Qgc2hfYnVmX2dldF9kaXJfc3RhcnQoc3RydWN0IHNoX2J1Zl9pbmZvICpi dWYpCit7CisJaWYgKCFidWYtPmdyZWZzKQorCQlyZXR1cm4gR1JBTlRfSU5WQUxJRF9SRUY7CisJ cmV0dXJuIGJ1Zi0+Z3JlZnNbMF07Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCBzaF9idWZfY2xl YXIoc3RydWN0IHNoX2J1Zl9pbmZvICpidWYpCit7CisJbWVtc2V0KGJ1ZiwgMCwgc2l6ZW9mKCpi dWYpKTsKK30KKworc3RhdGljIHZvaWQgc2hfYnVmX2ZyZWUoc3RydWN0IHNoX2J1Zl9pbmZvICpi dWYpCit7CisJaW50IGk7CisKKwlpZiAoYnVmLT5ncmVmcykgeworCQlmb3IgKGkgPSAwOyBpIDwg YnVmLT5udW1fZ3JlZnM7IGkrKykKKwkJCWlmIChidWYtPmdyZWZzW2ldICE9IEdSQU5UX0lOVkFM SURfUkVGKQorCQkJCWdudHRhYl9lbmRfZm9yZWlnbl9hY2Nlc3MoYnVmLT5ncmVmc1tpXSwKKwkJ CQkJCTAsIDBVTCk7CisJCWtmcmVlKGJ1Zi0+Z3JlZnMpOworCX0KKwlrZnJlZShidWYtPnZkaXJl Y3RvcnkpOworCWZyZWVfcGFnZXNfZXhhY3QoYnVmLT52YnVmZmVyLCBidWYtPnZidWZmZXJfc3op OworCXNoX2J1Zl9jbGVhcihidWYpOworfQorCisvKgorICogbnVtYmVyIG9mIGdyYW50IHJlZmVy ZW5jZXMgYSBwYWdlIGNhbiBob2xkIHdpdGggcmVzcGVjdCB0byB0aGUKKyAqIHhlbmRpc3BsX3Bh Z2VfZGlyZWN0b3J5IGhlYWRlcgorICovCisjZGVmaW5lIFhFTlNORF9OVU1fR1JFRlNfUEVSX1BB R0UgKChYRU5fUEFHRV9TSVpFIC0gXAorCW9mZnNldG9mKHN0cnVjdCB4ZW5zbmRfcGFnZV9kaXJl Y3RvcnksIGdyZWYpKSAvIFwKKwlzaXplb2YoZ3JhbnRfcmVmX3QpKQorCitzdGF0aWMgdm9pZCBz aF9idWZfZmlsbF9wYWdlX2RpcihzdHJ1Y3Qgc2hfYnVmX2luZm8gKmJ1ZiwgaW50IG51bV9wYWdl c19kaXIpCit7CisJc3RydWN0IHhlbnNuZF9wYWdlX2RpcmVjdG9yeSAqcGFnZV9kaXI7CisJdW5z aWduZWQgY2hhciAqcHRyOworCWludCBpLCBjdXJfZ3JlZiwgZ3JlZnNfbGVmdCwgdG9fY29weTsK KworCXB0ciA9IGJ1Zi0+dmRpcmVjdG9yeTsKKwlncmVmc19sZWZ0ID0gYnVmLT5udW1fZ3JlZnMg LSBudW1fcGFnZXNfZGlyOworCS8qCisJICogc2tpcCBncmFudCByZWZlcmVuY2VzIGF0IHRoZSBi ZWdpbm5pbmcsIHRoZXkgYXJlIGZvciBwYWdlcyBncmFudGVkCisJICogZm9yIHRoZSBwYWdlIGRp cmVjdG9yeSBpdHNlbGYKKwkgKi8KKwljdXJfZ3JlZiA9IG51bV9wYWdlc19kaXI7CisJZm9yIChp ID0gMDsgaSA8IG51bV9wYWdlc19kaXI7IGkrKykgeworCQlwYWdlX2RpciA9IChzdHJ1Y3QgeGVu c25kX3BhZ2VfZGlyZWN0b3J5ICopcHRyOworCQlpZiAoZ3JlZnNfbGVmdCA8PSBYRU5TTkRfTlVN X0dSRUZTX1BFUl9QQUdFKSB7CisJCQl0b19jb3B5ID0gZ3JlZnNfbGVmdDsKKwkJCXBhZ2VfZGly LT5ncmVmX2Rpcl9uZXh0X3BhZ2UgPSBHUkFOVF9JTlZBTElEX1JFRjsKKwkJfSBlbHNlIHsKKwkJ CXRvX2NvcHkgPSBYRU5TTkRfTlVNX0dSRUZTX1BFUl9QQUdFOworCQkJcGFnZV9kaXItPmdyZWZf ZGlyX25leHRfcGFnZSA9IGJ1Zi0+Z3JlZnNbaSArIDFdOworCQl9CisJCW1lbWNweSgmcGFnZV9k aXItPmdyZWYsICZidWYtPmdyZWZzW2N1cl9ncmVmXSwKKwkJCXRvX2NvcHkgKiBzaXplb2YoZ3Jh bnRfcmVmX3QpKTsKKwkJcHRyICs9IFhFTl9QQUdFX1NJWkU7CisJCWdyZWZzX2xlZnQgLT0gdG9f Y29weTsKKwkJY3VyX2dyZWYgKz0gdG9fY29weTsKKwl9Cit9CisKK3N0YXRpYyBpbnQgc2hfYnVm X2dyYW50X3JlZnMoc3RydWN0IHhlbmJ1c19kZXZpY2UgKnhiX2RldiwKKwlzdHJ1Y3Qgc2hfYnVm X2luZm8gKmJ1ZiwKKwlpbnQgbnVtX3BhZ2VzX2RpciwgaW50IG51bV9wYWdlc192YnVmZmVyLCBp bnQgbnVtX2dyZWZzKQoreworCWdyYW50X3JlZl90IHByaXZfZ3JlZl9oZWFkOworCWludCByZXQs IGksIGosIGN1cl9yZWY7CisJaW50IG90aGVyZW5kX2lkOworCisJcmV0ID0gZ250dGFiX2FsbG9j X2dyYW50X3JlZmVyZW5jZXMobnVtX2dyZWZzLCAmcHJpdl9ncmVmX2hlYWQpOworCWlmIChyZXQp CisJCXJldHVybiByZXQ7CisKKwlidWYtPm51bV9ncmVmcyA9IG51bV9ncmVmczsKKwlvdGhlcmVu ZF9pZCA9IHhiX2Rldi0+b3RoZXJlbmRfaWQ7CisJaiA9IDA7CisKKwlmb3IgKGkgPSAwOyBpIDwg bnVtX3BhZ2VzX2RpcjsgaSsrKSB7CisJCWN1cl9yZWYgPSBnbnR0YWJfY2xhaW1fZ3JhbnRfcmVm ZXJlbmNlKCZwcml2X2dyZWZfaGVhZCk7CisJCWlmIChjdXJfcmVmIDwgMCkgeworCQkJcmV0ID0g Y3VyX3JlZjsKKwkJCWdvdG8gZmFpbDsKKwkJfQorCisJCWdudHRhYl9ncmFudF9mb3JlaWduX2Fj Y2Vzc19yZWYoY3VyX3JlZiwgb3RoZXJlbmRfaWQsCisJCQl4ZW5fcGFnZV90b19nZm4odmlydF90 b19wYWdlKGJ1Zi0+dmRpcmVjdG9yeSArCisJCQkJWEVOX1BBR0VfU0laRSAqIGkpKSwgMCk7CisJ CWJ1Zi0+Z3JlZnNbaisrXSA9IGN1cl9yZWY7CisJfQorCisJZm9yIChpID0gMDsgaSA8IG51bV9w YWdlc192YnVmZmVyOyBpKyspIHsKKwkJY3VyX3JlZiA9IGdudHRhYl9jbGFpbV9ncmFudF9yZWZl cmVuY2UoJnByaXZfZ3JlZl9oZWFkKTsKKwkJaWYgKGN1cl9yZWYgPCAwKSB7CisJCQlyZXQgPSBj dXJfcmVmOworCQkJZ290byBmYWlsOworCQl9CisKKwkJZ250dGFiX2dyYW50X2ZvcmVpZ25fYWNj ZXNzX3JlZihjdXJfcmVmLCBvdGhlcmVuZF9pZCwKKwkJCXhlbl9wYWdlX3RvX2dmbih2aXJ0X3Rv X3BhZ2UoYnVmLT52YnVmZmVyICsKKwkJCQlYRU5fUEFHRV9TSVpFICogaSkpLCAwKTsKKwkJYnVm LT5ncmVmc1tqKytdID0gY3VyX3JlZjsKKwl9CisKKwlnbnR0YWJfZnJlZV9ncmFudF9yZWZlcmVu Y2VzKHByaXZfZ3JlZl9oZWFkKTsKKwlzaF9idWZfZmlsbF9wYWdlX2RpcihidWYsIG51bV9wYWdl c19kaXIpOworCXJldHVybiAwOworCitmYWlsOgorCWdudHRhYl9mcmVlX2dyYW50X3JlZmVyZW5j ZXMocHJpdl9ncmVmX2hlYWQpOworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgc2hfYnVm X2FsbG9jX2ludF9idWZmZXJzKHN0cnVjdCBzaF9idWZfaW5mbyAqYnVmLAorCQlpbnQgbnVtX3Bh Z2VzX2RpciwgaW50IG51bV9wYWdlc192YnVmZmVyLCBpbnQgbnVtX2dyZWZzKQoreworCWJ1Zi0+ Z3JlZnMgPSBrY2FsbG9jKG51bV9ncmVmcywgc2l6ZW9mKCpidWYtPmdyZWZzKSwgR0ZQX0tFUk5F TCk7CisJaWYgKCFidWYtPmdyZWZzKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWJ1Zi0+dmRpcmVj dG9yeSA9IGtjYWxsb2MobnVtX3BhZ2VzX2RpciwgWEVOX1BBR0VfU0laRSwgR0ZQX0tFUk5FTCk7 CisJaWYgKCFidWYtPnZkaXJlY3RvcnkpCisJCWdvdG8gZmFpbDsKKworCWJ1Zi0+dmJ1ZmZlcl9z eiA9IG51bV9wYWdlc192YnVmZmVyICogWEVOX1BBR0VfU0laRTsKKwlidWYtPnZidWZmZXIgPSBh bGxvY19wYWdlc19leGFjdChidWYtPnZidWZmZXJfc3osIEdGUF9LRVJORUwpOworCWlmICghYnVm LT52YnVmZmVyKQorCQlnb3RvIGZhaWw7CisJcmV0dXJuIDA7CisKK2ZhaWw6CisJa2ZyZWUoYnVm LT5ncmVmcyk7CisJYnVmLT5ncmVmcyA9IE5VTEw7CisJa2ZyZWUoYnVmLT52ZGlyZWN0b3J5KTsK KwlidWYtPnZkaXJlY3RvcnkgPSBOVUxMOworCXJldHVybiAtRU5PTUVNOworfQorCitzdGF0aWMg aW50IHNoX2J1Zl9hbGxvYyhzdHJ1Y3QgeGVuYnVzX2RldmljZSAqeGJfZGV2LAorCXN0cnVjdCBz aF9idWZfaW5mbyAqYnVmLCB1bnNpZ25lZCBpbnQgYnVmZmVyX3NpemUpCit7CisJaW50IG51bV9w YWdlc192YnVmZmVyLCBudW1fcGFnZXNfZGlyLCBudW1fZ3JlZnM7CisJaW50IHJldDsKKworCXNo X2J1Zl9jbGVhcihidWYpOworCisJbnVtX3BhZ2VzX3ZidWZmZXIgPSBESVZfUk9VTkRfVVAoYnVm ZmVyX3NpemUsIFhFTl9QQUdFX1NJWkUpOworCS8qIG51bWJlciBvZiBwYWdlcyB0aGUgcGFnZSBk aXJlY3RvcnkgY29uc3VtZXMgaXRzZWxmICovCisJbnVtX3BhZ2VzX2RpciA9IERJVl9ST1VORF9V UChudW1fcGFnZXNfdmJ1ZmZlciwKKwkJWEVOU05EX05VTV9HUkVGU19QRVJfUEFHRSk7CisJbnVt X2dyZWZzID0gbnVtX3BhZ2VzX3ZidWZmZXIgKyBudW1fcGFnZXNfZGlyOworCisJcmV0ID0gc2hf YnVmX2FsbG9jX2ludF9idWZmZXJzKGJ1ZiwgbnVtX3BhZ2VzX2RpciwKKwkJbnVtX3BhZ2VzX3Zi dWZmZXIsIG51bV9ncmVmcyk7CisJaWYgKHJldCA8IDApCisJCXJldHVybiByZXQ7CisKKwlyZXQg PSBzaF9idWZfZ3JhbnRfcmVmcyh4Yl9kZXYsIGJ1ZiwKKwkJbnVtX3BhZ2VzX2RpciwgbnVtX3Bh Z2VzX3ZidWZmZXIsIG51bV9ncmVmcyk7CisJaWYgKHJldCA8IDApCisJCXJldHVybiByZXQ7CisK KwlzaF9idWZfZmlsbF9wYWdlX2RpcihidWYsIG51bV9wYWdlc19kaXIpOworCXJldHVybiAwOwor fQorCiBzdGF0aWMgaW50IHhkcnZfYmVfb25faW5pdHdhaXQoc3RydWN0IHhkcnZfaW5mbyAqZHJ2 X2luZm8pCiB7CiAJaW50IHN0cmVhbV9pZHg7Ci0tIAoyLjcuNAoKCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QKWGVu LWRldmVsQGxpc3RzLnhlbi5vcmcKaHR0cHM6Ly9saXN0cy54ZW4ub3JnL3hlbi1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753330AbdHGLxw (ORCPT ); Mon, 7 Aug 2017 07:53:52 -0400 Received: from mail-lf0-f68.google.com ([209.85.215.68]:37317 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753279AbdHGLvB (ORCPT ); Mon, 7 Aug 2017 07:51:01 -0400 From: Oleksandr Andrushchenko To: alsa-devel@alsa-project.org, xen-devel@lists.xen.org, linux-kernel@vger.kernel.org Cc: perex@perex.cz, tiwai@suse.com, andr2000@gmail.com, Oleksandr Andrushchenko Subject: [PATCH RESEND 05/11] ALSA: vsnd: Implement handling of shared buffers Date: Mon, 7 Aug 2017 14:50:39 +0300 Message-Id: <1502106645-6731-6-git-send-email-andr2000@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502106645-6731-1-git-send-email-andr2000@gmail.com> References: <1502106645-6731-1-git-send-email-andr2000@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Oleksandr Andrushchenko Implement shared buffer handling according to the para-virtualized sound device protocol at xen/interface/io/sndif.h: - manage buffer memory - handle granted references - handle page directories Signed-off-by: Oleksandr Andrushchenko --- sound/drivers/xen-front.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c index a92459b2737e..04ebc15757f4 100644 --- a/sound/drivers/xen-front.c +++ b/sound/drivers/xen-front.c @@ -58,6 +58,14 @@ struct xdrv_evtchnl_info { uint16_t resp_id; }; +struct sh_buf_info { + int num_grefs; + grant_ref_t *grefs; + uint8_t *vdirectory; + uint8_t *vbuffer; + size_t vbuffer_sz; +}; + struct cfg_stream { int unique_id; char *xenstore_path; @@ -825,6 +833,176 @@ static void xdrv_remove_internal(struct xdrv_info *drv_info) xdrv_evtchnl_free_all(drv_info); } +static inline grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf) +{ + if (!buf->grefs) + return GRANT_INVALID_REF; + return buf->grefs[0]; +} + +static inline void sh_buf_clear(struct sh_buf_info *buf) +{ + memset(buf, 0, sizeof(*buf)); +} + +static void sh_buf_free(struct sh_buf_info *buf) +{ + int i; + + if (buf->grefs) { + for (i = 0; i < buf->num_grefs; i++) + if (buf->grefs[i] != GRANT_INVALID_REF) + gnttab_end_foreign_access(buf->grefs[i], + 0, 0UL); + kfree(buf->grefs); + } + kfree(buf->vdirectory); + free_pages_exact(buf->vbuffer, buf->vbuffer_sz); + sh_buf_clear(buf); +} + +/* + * number of grant references a page can hold with respect to the + * xendispl_page_directory header + */ +#define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \ + offsetof(struct xensnd_page_directory, gref)) / \ + sizeof(grant_ref_t)) + +static void sh_buf_fill_page_dir(struct sh_buf_info *buf, int num_pages_dir) +{ + struct xensnd_page_directory *page_dir; + unsigned char *ptr; + int i, cur_gref, grefs_left, to_copy; + + ptr = buf->vdirectory; + grefs_left = buf->num_grefs - num_pages_dir; + /* + * skip grant references at the beginning, they are for pages granted + * for the page directory itself + */ + cur_gref = num_pages_dir; + for (i = 0; i < num_pages_dir; i++) { + page_dir = (struct xensnd_page_directory *)ptr; + if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) { + to_copy = grefs_left; + page_dir->gref_dir_next_page = GRANT_INVALID_REF; + } else { + to_copy = XENSND_NUM_GREFS_PER_PAGE; + page_dir->gref_dir_next_page = buf->grefs[i + 1]; + } + memcpy(&page_dir->gref, &buf->grefs[cur_gref], + to_copy * sizeof(grant_ref_t)); + ptr += XEN_PAGE_SIZE; + grefs_left -= to_copy; + cur_gref += to_copy; + } +} + +static int sh_buf_grant_refs(struct xenbus_device *xb_dev, + struct sh_buf_info *buf, + int num_pages_dir, int num_pages_vbuffer, int num_grefs) +{ + grant_ref_t priv_gref_head; + int ret, i, j, cur_ref; + int otherend_id; + + ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head); + if (ret) + return ret; + + buf->num_grefs = num_grefs; + otherend_id = xb_dev->otherend_id; + j = 0; + + for (i = 0; i < num_pages_dir; i++) { + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); + if (cur_ref < 0) { + ret = cur_ref; + goto fail; + } + + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, + xen_page_to_gfn(virt_to_page(buf->vdirectory + + XEN_PAGE_SIZE * i)), 0); + buf->grefs[j++] = cur_ref; + } + + for (i = 0; i < num_pages_vbuffer; i++) { + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); + if (cur_ref < 0) { + ret = cur_ref; + goto fail; + } + + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, + xen_page_to_gfn(virt_to_page(buf->vbuffer + + XEN_PAGE_SIZE * i)), 0); + buf->grefs[j++] = cur_ref; + } + + gnttab_free_grant_references(priv_gref_head); + sh_buf_fill_page_dir(buf, num_pages_dir); + return 0; + +fail: + gnttab_free_grant_references(priv_gref_head); + return ret; +} + +static int sh_buf_alloc_int_buffers(struct sh_buf_info *buf, + int num_pages_dir, int num_pages_vbuffer, int num_grefs) +{ + buf->grefs = kcalloc(num_grefs, sizeof(*buf->grefs), GFP_KERNEL); + if (!buf->grefs) + return -ENOMEM; + + buf->vdirectory = kcalloc(num_pages_dir, XEN_PAGE_SIZE, GFP_KERNEL); + if (!buf->vdirectory) + goto fail; + + buf->vbuffer_sz = num_pages_vbuffer * XEN_PAGE_SIZE; + buf->vbuffer = alloc_pages_exact(buf->vbuffer_sz, GFP_KERNEL); + if (!buf->vbuffer) + goto fail; + return 0; + +fail: + kfree(buf->grefs); + buf->grefs = NULL; + kfree(buf->vdirectory); + buf->vdirectory = NULL; + return -ENOMEM; +} + +static int sh_buf_alloc(struct xenbus_device *xb_dev, + struct sh_buf_info *buf, unsigned int buffer_size) +{ + int num_pages_vbuffer, num_pages_dir, num_grefs; + int ret; + + sh_buf_clear(buf); + + num_pages_vbuffer = DIV_ROUND_UP(buffer_size, XEN_PAGE_SIZE); + /* number of pages the page directory consumes itself */ + num_pages_dir = DIV_ROUND_UP(num_pages_vbuffer, + XENSND_NUM_GREFS_PER_PAGE); + num_grefs = num_pages_vbuffer + num_pages_dir; + + ret = sh_buf_alloc_int_buffers(buf, num_pages_dir, + num_pages_vbuffer, num_grefs); + if (ret < 0) + return ret; + + ret = sh_buf_grant_refs(xb_dev, buf, + num_pages_dir, num_pages_vbuffer, num_grefs); + if (ret < 0) + return ret; + + sh_buf_fill_page_dir(buf, num_pages_dir); + return 0; +} + static int xdrv_be_on_initwait(struct xdrv_info *drv_info) { int stream_idx; -- 2.7.4