* [RFC v2 3/3] proc: add kpageidle file
From: Vladimir Davydov @ 2015-04-07 11:55 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
In-Reply-To: <cover.1428401673.git.vdavydov@parallels.com>
Knowing the portion of memory that is not used by a certain application
or memory cgroup (idle memory) can be useful for partitioning the system
efficiently, e.g. by setting memory cgroup limits appropriately.
Currently, the only means to estimate the amount of idle memory provided
by the kernel is /proc/PID/{clear_refs,smaps}: the user can clear the
access bit for all pages mapped to a particular process by writing 1 to
clear_refs, wait for some time, and then count smaps:Referenced.
However, this method has two serious shortcomings:
- it does not count unmapped file pages
- it affects the reclaimer logic
To overcome these drawbacks, this patch introduces two new page flags,
Idle and Young, and a new proc file, /proc/kpageidle. A page's Idle flag
can only be set from userspace by writing to /proc/kpageidle at the
offset corresponding to the page, and it is cleared whenever the page is
accessed either through page tables (it is cleared in page_referenced()
in this case) or using the read(2) system call (mark_page_accessed()).
Thus by setting the Idle flag for pages of a particular workload, which
can be found e.g. by reading /proc/PID/pagemap, waiting for some time to
let the workload access its working set, and then reading the kpageidle
file, one can estimate the amount of pages that are not used by the
workload.
The Young page flag is used to avoid interference with the memory
reclaimer. A page's Young flag is set whenever the Access bit of a page
table entry pointing to the page is cleared by writing to kpageidle. If
page_referenced() is called on a Young page, it will add 1 to its return
value, therefore concealing the fact that the Access bit was cleared.
Since this new feature adds two extra page flags, it is made dependant
on 64BIT, where we have plenty of space for page flags. We could use
page_ext to accomodate new flags on 32BIT, but this is left for the
future work.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
---
Documentation/vm/pagemap.txt | 17 ++++-
fs/proc/page.c | 149 ++++++++++++++++++++++++++++++++++++++++++
fs/proc/task_mmu.c | 4 +-
include/linux/page-flags.h | 12 ++++
mm/Kconfig | 12 ++++
mm/debug.c | 4 ++
mm/rmap.c | 7 ++
mm/swap.c | 2 +
8 files changed, 205 insertions(+), 2 deletions(-)
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 1ddfa1367b03..2ab2d5b98e8d 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -5,7 +5,7 @@ pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow
userspace programs to examine the page tables and related information by
reading files in /proc.
-There are four components to pagemap:
+There are five components to pagemap:
* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
@@ -69,6 +69,21 @@ There are four components to pagemap:
memory cgroup each page is charged to, indexed by PFN. Only available when
CONFIG_MEMCG is set.
+ * /proc/kpageidle. For each page this file contains a 64-bit number, which
+ equals 1 if the page is idle or 0 otherwise. The file is indexed by PFN. To
+ set or clear a page's Idle flag, one can write 1 or 0 respectively to this
+ file at the offset corresponding to the page. It is only possible to modify
+ the Idle flag for user pages (pages that are on an LRU list, to be more
+ exact). For other page types, the input is silently ignored. Writing to this
+ file beyond max PFN results in the ENXIO error.
+
+ A page's Idle flag is automatically cleared whenever the page is accessed
+ (via a page table entry or using the read(2) system call). This makes this
+ file useful for tracking a workload's working set, i.e. the set of pages
+ that are actively used by the workload.
+
+ The file is only available when CONFIG_IDLE_PAGE_TRACKING is set.
+
Short descriptions to the page flags:
0. LOCKED
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 70d23245dd43..974498a4c4b4 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -275,6 +275,151 @@ static const struct file_operations proc_kpagecgroup_operations = {
};
#endif /* CONFIG_MEMCG */
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+static struct page *kpageidle_get_page(struct page *page)
+{
+ if (!page || page_count(page) == 0 || !PageLRU(page))
+ return NULL;
+ if (!get_page_unless_zero(page))
+ return NULL;
+ if (unlikely(!PageLRU(page))) {
+ put_page(page);
+ return NULL;
+ }
+ return page;
+}
+
+static void kpageidle_clear_refs(struct page *page)
+{
+ unsigned long dummy;
+
+ if (page_referenced(page, 0, NULL, &dummy, NULL))
+ SetPageYoung(page);
+}
+
+static u64 kpageidle_read_page_state(struct page *page)
+{
+ u64 state = 0;
+
+ page = kpageidle_get_page(page);
+ if (!page)
+ return 0;
+ if (PageIdle(page)) {
+ kpageidle_clear_refs(page);
+ if (PageIdle(page))
+ state = 1;
+ }
+ put_page(page);
+ return state;
+}
+
+static int kpageidle_write_page_state(struct page *page, u64 state)
+{
+ if (state != 0 && state != 1)
+ return -EINVAL;
+ page = kpageidle_get_page(page);
+ if (!page)
+ return 0;
+ if (state && !PageIdle(page)) {
+ kpageidle_clear_refs(page);
+ SetPageIdle(page);
+ } else if (!state && PageIdle(page))
+ ClearPageIdle(page);
+ put_page(page);
+ return 0;
+}
+
+static ssize_t kpageidle_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ u64 __user *out = (u64 __user *)buf;
+ struct page *ppage;
+ unsigned long src = *ppos;
+ unsigned long pfn;
+ ssize_t ret = 0;
+ u64 val;
+
+ pfn = src / KPMSIZE;
+ count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
+ if (src & KPMMASK || count & KPMMASK)
+ return -EINVAL;
+
+ while (count > 0) {
+ if (pfn_valid(pfn))
+ ppage = pfn_to_page(pfn);
+ else
+ ppage = NULL;
+
+ val = kpageidle_read_page_state(ppage);
+
+ if (put_user(val, out)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ pfn++;
+ out++;
+ count -= KPMSIZE;
+ }
+
+ *ppos += (char __user *)out - buf;
+ if (!ret)
+ ret = (char __user *)out - buf;
+ return ret;
+}
+
+static ssize_t kpageidle_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ const u64 __user *in = (u64 __user *)buf;
+ struct page *ppage;
+ unsigned long src = *ppos;
+ unsigned long pfn;
+ ssize_t ret = 0;
+ u64 val;
+
+ pfn = src / KPMSIZE;
+ if (src & KPMMASK || count & KPMMASK)
+ return -EINVAL;
+
+ while (count > 0) {
+ if (pfn >= max_pfn) {
+ if ((char __user *)in == buf)
+ ret = -ENXIO;
+ break;
+ }
+ if (pfn_valid(pfn))
+ ppage = pfn_to_page(pfn);
+ else
+ ppage = NULL;
+
+ if (get_user(val, in)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = kpageidle_write_page_state(ppage, val);
+ if (ret)
+ break;
+
+ pfn++;
+ in++;
+ count -= KPMSIZE;
+ }
+
+ *ppos += (char __user *)in - buf;
+ if (!ret)
+ ret = (char __user *)in - buf;
+ return ret;
+}
+
+static const struct file_operations proc_kpageidle_operations = {
+ .llseek = mem_lseek,
+ .read = kpageidle_read,
+ .write = kpageidle_write,
+};
+#endif /* CONFIG_IDLE_PAGE_TRACKING */
+
static int __init proc_page_init(void)
{
proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
@@ -282,6 +427,10 @@ static int __init proc_page_init(void)
#ifdef CONFIG_MEMCG
proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations);
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+ proc_create("kpageidle", S_IRUSR | S_IWUSR, NULL,
+ &proc_kpageidle_operations);
+#endif
return 0;
}
fs_initcall(proc_page_init);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 6dee68d013ff..5ed5f707cac3 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -458,7 +458,7 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
mss->resident += size;
/* Accumulate the size in pages that have been accessed. */
- if (young || PageReferenced(page))
+ if (young || PageYoung(page) || PageReferenced(page))
mss->referenced += size;
mapcount = page_mapcount(page);
if (mapcount >= 2) {
@@ -808,6 +808,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
/* Clear accessed and referenced bits. */
pmdp_test_and_clear_young(vma, addr, pmd);
+ ClearPageYoung(page);
ClearPageReferenced(page);
out:
spin_unlock(ptl);
@@ -835,6 +836,7 @@ out:
/* Clear accessed and referenced bits. */
ptep_test_and_clear_young(vma, addr, pte);
+ ClearPageYoung(page);
ClearPageReferenced(page);
}
pte_unmap_unlock(pte - 1, ptl);
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 91b7f9b2b774..e53afb2738f8 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -109,6 +109,10 @@ enum pageflags {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
PG_compound_lock,
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+ PG_young,
+ PG_idle,
+#endif
__NR_PAGEFLAGS,
/* Filesystems */
@@ -363,6 +367,14 @@ PAGEFLAG_FALSE(HWPoison)
#define __PG_HWPOISON 0
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+PAGEFLAG(Young, young, PF_HEAD)
+PAGEFLAG(Idle, idle, PF_HEAD)
+#else
+PAGEFLAG_FALSE(Young)
+PAGEFLAG_FALSE(Idle)
+#endif
+
/*
* On an anonymous page mapped into a user virtual memory area,
* page->mapping points to its anon_vma, not to a struct address_space;
diff --git a/mm/Kconfig b/mm/Kconfig
index 390214da4546..880dffd9fce1 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -635,3 +635,15 @@ config MAX_STACK_SIZE_MB
changed to a smaller value in which case that is used.
A sane initial value is 80 MB.
+
+config IDLE_PAGE_TRACKING
+ bool "Enable idle page tracking"
+ depends on 64BIT
+ select PROC_PAGE_MONITOR
+ help
+ This feature allows to estimate the amount of user pages that have
+ not been touched during a given period of time. This information can
+ be useful to tune memory cgroup limits and/or for job placement
+ within a compute cluster.
+
+ See Documentation/vm/pagemap.txt for more details.
diff --git a/mm/debug.c b/mm/debug.c
index 3eb3ac2fcee7..25d58478f59b 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -48,6 +48,10 @@ static const struct trace_print_flags pageflag_names[] = {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
{1UL << PG_compound_lock, "compound_lock" },
#endif
+#ifdef CONFIG_IDLE_PAGE_TRACKING
+ {1UL << PG_young, "young" },
+ {1UL << PG_idle, "idle" },
+#endif
};
static void dump_flags(unsigned long flags,
diff --git a/mm/rmap.c b/mm/rmap.c
index dad23a43e42c..b6ead8a13185 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -799,6 +799,13 @@ static int page_referenced_one(struct page *page, struct vm_area_struct *vma,
if (referenced) {
pra->referenced++;
pra->vm_flags |= vma->vm_flags;
+ if (PageIdle(page))
+ ClearPageIdle(page);
+ }
+
+ if (PageYoung(page)) {
+ ClearPageYoung(page);
+ pra->referenced++;
}
if (dirty)
diff --git a/mm/swap.c b/mm/swap.c
index 8773de093171..bee91fab10fc 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -624,6 +624,8 @@ void mark_page_accessed(struct page *page)
} else if (!PageReferenced(page)) {
SetPageReferenced(page);
}
+ if (PageIdle(page))
+ ClearPageIdle(page);
}
EXPORT_SYMBOL(mark_page_accessed);
--
1.7.10.4
^ permalink raw reply related
* Re: [RFC v2 0/3] idle memory tracking
From: Vladimir Davydov @ 2015-04-07 12:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Minchan Kim, Johannes Weiner, Michal Hocko, Greg Thelen,
Michel Lespinasse, David Rientjes, Pavel Emelyanov,
Cyrill Gorcunov, Jonathan Corbet, linux-api, linux-doc, linux-mm,
cgroups, linux-kernel
In-Reply-To: <cover.1428401673.git.vdavydov@parallels.com>
Forgot to mention:
Originally, the patch for tracking idle memory was proposed back in 2011
by Michel Lespinasse (see http://lwn.net/Articles/459269/). The main
difference between Michel's patch and this one is that Michel
implemented a kernel space daemon for estimating idle memory size per
cgroup while this patch only provides the userspace with the minimal API
for doing the job, leaving the rest up to the userspace. However, they
both share the same idea of Idle/Young page flags to avoid affecting the
reclaimer logic.
^ permalink raw reply
* [PATCH v3 0/7] vhost: support for cross endian guests
From: Greg Kurz @ 2015-04-07 12:09 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Hi,
This patchset allows vhost to be used with legacy virtio when guest and host
have a different endianness.
Patches 1-6 remain the same as the previous post. Patch 7 was heavily changed
according to MST's comments.
---
Greg Kurz (7):
virtio: introduce virtio_is_little_endian() helper
tun: add tun_is_little_endian() helper
macvtap: introduce macvtap_is_little_endian() helper
vringh: introduce vringh_is_little_endian() helper
vhost: introduce vhost_is_little_endian() helper
virtio: add explicit big-endian support to memory accessors
vhost: feature to set the vring endianness
drivers/net/macvtap.c | 11 ++++++--
drivers/net/tun.c | 11 ++++++--
drivers/vhost/Kconfig | 10 +++++++
drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++
drivers/vhost/vhost.h | 34 +++++++++++++++++++----
include/linux/virtio_byteorder.h | 24 ++++++++++-------
include/linux/virtio_config.h | 19 +++++++++----
include/linux/vringh.h | 19 +++++++++----
include/uapi/linux/vhost.h | 5 +++
9 files changed, 156 insertions(+), 32 deletions(-)
--
Greg
^ permalink raw reply
* [PATCH v3 1/7] virtio: introduce virtio_is_little_endian() helper
From: Greg Kurz @ 2015-04-07 12:09 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
include/linux/virtio_config.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index ca3ed78..bd1a582 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -205,35 +205,40 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
return 0;
}
+static inline bool virtio_is_little_endian(struct virtio_device *vdev)
+{
+ return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
+}
+
/* Memory accessors */
static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
{
- return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
{
- return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
}
static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
{
- return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
{
- return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
}
static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
{
- return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
}
static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
{
- return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
}
/* Config space accessors. */
^ permalink raw reply related
* [PATCH v3 2/7] tun: add tun_is_little_endian() helper
From: Greg Kurz @ 2015-04-07 12:09 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
drivers/net/tun.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 857dca4..3c3d6c0 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -206,14 +206,19 @@ struct tun_struct {
u32 flow_count;
};
+static inline bool tun_is_little_endian(struct tun_struct *tun)
+{
+ return tun->flags & TUN_VNET_LE;
+}
+
static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
{
- return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val);
+ return __virtio16_to_cpu(tun_is_little_endian(tun), val);
}
static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val)
{
- return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val);
+ return __cpu_to_virtio16(tun_is_little_endian(tun), val);
}
static inline u32 tun_hashfn(u32 rxhash)
^ permalink raw reply related
* [PATCH v3 3/7] macvtap: introduce macvtap_is_little_endian() helper
From: Greg Kurz @ 2015-04-07 12:09 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
drivers/net/macvtap.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 27ecc5c..a2f2958 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -49,14 +49,19 @@ struct macvtap_queue {
#define MACVTAP_VNET_LE 0x80000000
+static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
+{
+ return q->flags & MACVTAP_VNET_LE;
+}
+
static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
{
- return __virtio16_to_cpu(q->flags & MACVTAP_VNET_LE, val);
+ return __virtio16_to_cpu(macvtap_is_little_endian(q), val);
}
static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val)
{
- return __cpu_to_virtio16(q->flags & MACVTAP_VNET_LE, val);
+ return __cpu_to_virtio16(macvtap_is_little_endian(q), val);
}
static struct proto macvtap_proto = {
^ permalink raw reply related
* [PATCH v3 4/7] vringh: introduce vringh_is_little_endian() helper
From: Greg Kurz @ 2015-04-07 12:15 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
include/linux/vringh.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index a3fa537..3ed62ef 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -226,33 +226,38 @@ static inline void vringh_notify(struct vringh *vrh)
vrh->notify(vrh);
}
+static inline bool vringh_is_little_endian(const struct vringh *vrh)
+{
+ return vrh->little_endian;
+}
+
static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
{
- return __virtio16_to_cpu(vrh->little_endian, val);
+ return __virtio16_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio16 cpu_to_vringh16(const struct vringh *vrh, u16 val)
{
- return __cpu_to_virtio16(vrh->little_endian, val);
+ return __cpu_to_virtio16(vringh_is_little_endian(vrh), val);
}
static inline u32 vringh32_to_cpu(const struct vringh *vrh, __virtio32 val)
{
- return __virtio32_to_cpu(vrh->little_endian, val);
+ return __virtio32_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio32 cpu_to_vringh32(const struct vringh *vrh, u32 val)
{
- return __cpu_to_virtio32(vrh->little_endian, val);
+ return __cpu_to_virtio32(vringh_is_little_endian(vrh), val);
}
static inline u64 vringh64_to_cpu(const struct vringh *vrh, __virtio64 val)
{
- return __virtio64_to_cpu(vrh->little_endian, val);
+ return __virtio64_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
{
- return __cpu_to_virtio64(vrh->little_endian, val);
+ return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
}
#endif /* _LINUX_VRINGH_H */
^ permalink raw reply related
* [PATCH v3 5/7] vhost: introduce vhost_is_little_endian() helper
From: Greg Kurz @ 2015-04-07 12:15 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
drivers/vhost/vhost.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 8c1c792..6a49960 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -173,34 +173,39 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
return vq->acked_features & (1ULL << bit);
}
+static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
+{
+ return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
+}
+
/* Memory accessors */
static inline u16 vhost16_to_cpu(struct vhost_virtqueue *vq, __virtio16 val)
{
- return __virtio16_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio16_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio16 cpu_to_vhost16(struct vhost_virtqueue *vq, u16 val)
{
- return __cpu_to_virtio16(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio16(vhost_is_little_endian(vq), val);
}
static inline u32 vhost32_to_cpu(struct vhost_virtqueue *vq, __virtio32 val)
{
- return __virtio32_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio32_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio32 cpu_to_vhost32(struct vhost_virtqueue *vq, u32 val)
{
- return __cpu_to_virtio32(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio32(vhost_is_little_endian(vq), val);
}
static inline u64 vhost64_to_cpu(struct vhost_virtqueue *vq, __virtio64 val)
{
- return __virtio64_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio64_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio64 cpu_to_vhost64(struct vhost_virtqueue *vq, u64 val)
{
- return __cpu_to_virtio64(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio64(vhost_is_little_endian(vq), val);
}
#endif
^ permalink raw reply related
* [PATCH v3 6/7] virtio: add explicit big-endian support to memory accessors
From: Greg Kurz @ 2015-04-07 12:15 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150407120929.4213.8225.stgit-to6p26YowclJmDnNpxttO7KMsZMIf1jtdfLczzV0R5oAvxtiuMwx3w@public.gmane.org>
The current memory accessors logic is:
- little endian if little_endian
- native endian (i.e. no byteswap) if !little_endian
If we want to fully support cross-endian vhost, we also need to be
able to convert to big endian.
Instead of changing the little_endian argument to some 3-value enum, this
patch changes the logic to:
- little endian if little_endian
- big endian if !little_endian
The native endian case is handled by all users with a trivial helper. This
patch doesn't change any functionality, nor it does add overhead.
Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
drivers/net/macvtap.c | 4 +++-
drivers/net/tun.c | 4 +++-
drivers/vhost/vhost.h | 4 +++-
include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
include/linux/virtio_config.h | 4 +++-
include/linux/vringh.h | 4 +++-
6 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index a2f2958..0a03a66 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -51,7 +51,9 @@ struct macvtap_queue {
static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
{
- return q->flags & MACVTAP_VNET_LE;
+ if (q->flags & MACVTAP_VNET_LE)
+ return true;
+ return virtio_legacy_is_little_endian();
}
static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3c3d6c0..053f9b6 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -208,7 +208,9 @@ struct tun_struct {
static inline bool tun_is_little_endian(struct tun_struct *tun)
{
- return tun->flags & TUN_VNET_LE;
+ if (tun->flags & TUN_VNET_LE)
+ return true;
+ return virtio_legacy_is_little_endian();
}
static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 6a49960..4e9a186 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -175,7 +175,9 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
{
- return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
+ if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
+ return true;
+ return virtio_legacy_is_little_endian();
}
/* Memory accessors */
diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h
index 51865d0..ce63a2c 100644
--- a/include/linux/virtio_byteorder.h
+++ b/include/linux/virtio_byteorder.h
@@ -3,17 +3,21 @@
#include <linux/types.h>
#include <uapi/linux/virtio_types.h>
-/*
- * Low-level memory accessors for handling virtio in modern little endian and in
- * compatibility native endian format.
- */
+static inline bool virtio_legacy_is_little_endian(void)
+{
+#ifdef __LITTLE_ENDIAN
+ return true;
+#else
+ return false;
+#endif
+}
static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
{
if (little_endian)
return le16_to_cpu((__force __le16)val);
else
- return (__force u16)val;
+ return be16_to_cpu((__force __be16)val);
}
static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
@@ -21,7 +25,7 @@ static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
if (little_endian)
return (__force __virtio16)cpu_to_le16(val);
else
- return (__force __virtio16)val;
+ return (__force __virtio16)cpu_to_be16(val);
}
static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
@@ -29,7 +33,7 @@ static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
if (little_endian)
return le32_to_cpu((__force __le32)val);
else
- return (__force u32)val;
+ return be32_to_cpu((__force __be32)val);
}
static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
@@ -37,7 +41,7 @@ static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
if (little_endian)
return (__force __virtio32)cpu_to_le32(val);
else
- return (__force __virtio32)val;
+ return (__force __virtio32)cpu_to_be32(val);
}
static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
@@ -45,7 +49,7 @@ static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
if (little_endian)
return le64_to_cpu((__force __le64)val);
else
- return (__force u64)val;
+ return be64_to_cpu((__force __be64)val);
}
static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
@@ -53,7 +57,7 @@ static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
if (little_endian)
return (__force __virtio64)cpu_to_le64(val);
else
- return (__force __virtio64)val;
+ return (__force __virtio64)cpu_to_be64(val);
}
#endif /* _LINUX_VIRTIO_BYTEORDER */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index bd1a582..36a6daa 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -207,7 +207,9 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
static inline bool virtio_is_little_endian(struct virtio_device *vdev)
{
- return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
+ if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
+ return true;
+ return virtio_legacy_is_little_endian();
}
/* Memory accessors */
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index 3ed62ef..d786c2d 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -228,7 +228,9 @@ static inline void vringh_notify(struct vringh *vrh)
static inline bool vringh_is_little_endian(const struct vringh *vrh)
{
- return vrh->little_endian;
+ if (vrh->little_endian)
+ return true;
+ return virtio_legacy_is_little_endian();
}
static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
^ permalink raw reply related
* [PATCH v3 7/7] vhost: feature to set the vring endianness
From: Greg Kurz @ 2015-04-07 12:19 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407120929.4213.8225.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
This patch brings cross-endian support to vhost when used to implement
legacy virtio devices. Since it is a relatively rare situation, the
feature availability is controlled by a kernel config option (not set
by default).
The ioctls introduced by this patch are for legacy only: virtio 1.0
devices are returned EPERM.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
drivers/vhost/Kconfig | 10 ++++++++
drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
drivers/vhost/vhost.h | 17 +++++++++++++-
include/uapi/linux/vhost.h | 5 ++++
4 files changed, 86 insertions(+), 1 deletion(-)
Changes since v2:
- fixed typos in Kconfig description
- renamed vq->legacy_big_endian to vq->legacy_is_little_endian
- vq->legacy_is_little_endian reset to default in vhost_vq_reset()
- dropped VHOST_F_SET_ENDIAN_LEGACY feature
- dropped struct vhost_vring_endian from the user API (re-use
struct vhost_vring_state instead)
- added VHOST_GET_VRING_ENDIAN_LEGACY ioctl
- introduced more helpers and stubs to avoid polluting the code with ifdefs
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 017a1e8..0aec88c 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -32,3 +32,13 @@ config VHOST
---help---
This option is selected by any driver which needs to access
the core of vhost.
+
+config VHOST_SET_ENDIAN_LEGACY
+ bool "Cross-endian support for host kernel accelerator"
+ default n
+ ---help---
+ This option allows vhost to support guests with a different byte
+ ordering from host. It is disabled by default since it adds overhead
+ and it is only needed by a few platforms (powerpc and arm).
+
+ If unsure, say "N".
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2ee2826..3529a3c 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -199,6 +199,7 @@ static void vhost_vq_reset(struct vhost_dev *dev,
vq->call = NULL;
vq->log_ctx = NULL;
vq->memory = NULL;
+ vq->legacy_is_little_endian = virtio_legacy_is_little_endian();
}
static int vhost_worker(void *data)
@@ -630,6 +631,54 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
return 0;
}
+#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
+static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
+ void __user *argp)
+{
+ struct vhost_vring_state s;
+
+ if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
+ return -EPERM;
+
+ if (copy_from_user(&s, argp, sizeof(s)))
+ return -EFAULT;
+
+ vq->legacy_is_little_endian = !!s.num;
+ return 0;
+}
+
+static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
+ u32 idx,
+ void __user *argp)
+{
+ struct vhost_vring_state s = {
+ .index = idx,
+ .num = vq->legacy_is_little_endian
+ };
+
+ if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
+ return -EPERM;
+
+ if (copy_to_user(argp, &s, sizeof(s)))
+ return -EFAULT;
+
+ return 0;
+}
+#else
+static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
+ void __user *argp)
+{
+ return 0;
+}
+
+static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
+ u32 idx,
+ void __user *argp)
+{
+ return 0;
+}
+#endif /* CONFIG_VHOST_SET_ENDIAN_LEGACY */
+
long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
{
struct file *eventfp, *filep = NULL;
@@ -806,6 +855,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
} else
filep = eventfp;
break;
+ case VHOST_SET_VRING_ENDIAN_LEGACY:
+ r = vhost_set_vring_endian_legacy(vq, argp);
+ break;
+ case VHOST_GET_VRING_ENDIAN_LEGACY:
+ r = vhost_get_vring_endian_legacy(vq, idx, argp);
+ break;
default:
r = -ENOIOCTLCMD;
}
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4e9a186..981ba06 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -106,6 +106,9 @@ struct vhost_virtqueue {
/* Log write descriptors */
void __user *log_base;
struct vhost_log *log;
+
+ /* We need to know the device endianness with legacy virtio. */
+ bool legacy_is_little_endian;
};
struct vhost_dev {
@@ -173,11 +176,23 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
return vq->acked_features & (1ULL << bit);
}
+#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
+static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
+{
+ return vq->legacy_is_little_endian;
+}
+#else
+static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
+{
+ return virtio_legacy_is_little_endian();
+}
+#endif
+
static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
{
if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
return true;
- return virtio_legacy_is_little_endian();
+ return vhost_legacy_is_little_endian(vq);
}
/* Memory accessors */
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index bb6a5b4..1b01a72 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -103,6 +103,11 @@ struct vhost_memory {
/* Get accessor: reads index, writes value in num */
#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+/* Set endianness for the ring (legacy virtio only) */
+/* num is 0 for big endian, other values mean little endian */
+#define VHOST_SET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
+#define VHOST_GET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
+
/* The following ioctls use eventfd file descriptors to signal and poll
* for events. */
^ permalink raw reply related
* Re: [PATCH v2] pci: export class IDs from pci_ids.h
From: Martin Mares @ 2015-04-07 12:57 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Bjorn Helgaas,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jonathan Corbet, David S. Miller, Hans Verkuil,
Mauro Carvalho Chehab, Alexei Starovoitov, stephen hemminger,
Masahiro Yamada,
linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-api-u79uwXL29TY76Z2rM5mHXA, Greg KH
In-Reply-To: <20150405132041-mutt-send-email-mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Hello!
> That's a good idea. Martin, could you please answer the following:
> assuming that linux exported linux/pci_ids.h providing class
> IDs that are currently in /usr/include/pci/header.h
> in a header /usr/include/linux/pci_ids.h,
> would libpci be open to replacing part of
> /usr/include/pci/header.h with #include <linux/pci_ids.h>,
> assuming that a solution for old systems that lack this
> header is also provided?
Please remember that libpci is cross-platform. Your proposal would make it
use <linux/pci_ids.h> on Linux and provide its own definitions on all other
systems, which is likely to bring less consistency, not more.
I do not see any point in using kernel headers for things, which are unrelated
to the kernel.
> pciutils does nothing with this value itself, it's possible for a distro
> to ship a wrong header, and no one will notice. OTOH Linux will break if
> it's wrong. In fact there are 3 values libpci does appear to use
> internally:
> PCI_CLASS_BRIDGE_HOST
> PCI_CLASS_DISPLAY_VGA
> PCI_CLASS_BRIDGE_PCI
>
> I'm guessing others are re-exported for the benefit of
> applications using libpci.
Exactly. And I expect that it will be quite similar with the kernel --
most classes defined in <linux/pci_ids.h> are not likely to be used anywhere
in the kernel.
Martin
^ permalink raw reply
* Re: [PATCH v3 7/7] vhost: feature to set the vring endianness
From: Cornelia Huck @ 2015-04-07 15:01 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150407121557.4213.95569.stgit-to6p26YowclJmDnNpxttO7KMsZMIf1jtdfLczzV0R5oAvxtiuMwx3w@public.gmane.org>
On Tue, 07 Apr 2015 14:19:31 +0200
Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> This patch brings cross-endian support to vhost when used to implement
> legacy virtio devices. Since it is a relatively rare situation, the
> feature availability is controlled by a kernel config option (not set
> by default).
>
> The ioctls introduced by this patch are for legacy only: virtio 1.0
> devices are returned EPERM.
>
> Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
> drivers/vhost/Kconfig | 10 ++++++++
> drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
> drivers/vhost/vhost.h | 17 +++++++++++++-
> include/uapi/linux/vhost.h | 5 ++++
> 4 files changed, 86 insertions(+), 1 deletion(-)
> +#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + struct vhost_vring_state s;
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
> +
> + if (copy_from_user(&s, argp, sizeof(s)))
> + return -EFAULT;
> +
> + vq->legacy_is_little_endian = !!s.num;
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + struct vhost_vring_state s = {
> + .index = idx,
> + .num = vq->legacy_is_little_endian
> + };
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
> +
> + if (copy_to_user(argp, &s, sizeof(s)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +#else
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + return 0;
I'm wondering whether this handler should return an error if the
feature is not configured for the kernel? How can the userspace caller
find out whether it has successfully prompted the kernel to handle the
endianness correctly?
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + return 0;
> +}
> +#endif /* CONFIG_VHOST_SET_ENDIAN_LEGACY */
^ permalink raw reply
* Re: [PATCH v5 09/15] dt-bindings: Document the STM32 USART bindings
From: Maxime Coquelin @ 2015-04-07 15:49 UTC (permalink / raw)
To: Rob Herring
Cc: Uwe Kleine-König, Andreas Färber, Geert Uytterhoeven,
Rob Herring, Philipp Zabel, Linus Walleij, Arnd Bergmann,
Stefan Agner, Peter Meerwald, Paul Bolle, Peter Hurley,
Andy Shevchenko, Chanwoo Choi, Russell King, Daniel Lezcano,
Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman
In-Reply-To: <CAL_JsqKioFc65Gng0FbOOBCspwxr1-bdy1kShKRM24XyALPmOw@mail.gmail.com>
2015-04-03 19:14 GMT+02:00 Rob Herring <robherring2@gmail.com>:
> On Fri, Apr 3, 2015 at 12:01 PM, Maxime Coquelin
> <mcoquelin.stm32@gmail.com> wrote:
>> This adds documentation of device tree bindings for the
>> STM32 USART
>>
>> Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>> .../devicetree/bindings/serial/st,stm32-usart.txt | 32 ++++++++++++++++++++++
>> 1 file changed, 32 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>>
>> diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>> new file mode 100644
>> index 0000000..090a3a4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>> @@ -0,0 +1,32 @@
>> +* STMicroelectronics STM32 USART
>> +
>> +Required properties:
>> +- compatible: Can be either "st,stm32-usart" or "st,stm32-uart" depending on
>> +whether the device supports synchronous mode.
>> +- reg: The address and length of the peripheral registers space
>> +- interrupts: The interrupt line of the USART instance
>> +- clocks: The input clock of the USART instance
>> +
>> +Optional properties:
>> +- pinctrl: The reference on the pins configuration
>> +- st,hw-flow-ctrl: bool flag to enable hardware flow control.
>
> We already have "auto-flow-control" for 8250. Does that work for you?
Yes it works, just that I didn't know about it.
I will change to "auto-flow-control" in next version.
Thanks,
Maxime
^ permalink raw reply
* Re: [PATCH v3 7/7] vhost: feature to set the vring endianness
From: Michael S. Tsirkin @ 2015-04-07 15:52 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150407121557.4213.95569.stgit-to6p26YowclJmDnNpxttO7KMsZMIf1jtdfLczzV0R5oAvxtiuMwx3w@public.gmane.org>
On Tue, Apr 07, 2015 at 02:19:31PM +0200, Greg Kurz wrote:
> This patch brings cross-endian support to vhost when used to implement
> legacy virtio devices. Since it is a relatively rare situation, the
> feature availability is controlled by a kernel config option (not set
> by default).
>
> The ioctls introduced by this patch are for legacy only: virtio 1.0
> devices are returned EPERM.
>
> Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
EINVAL probably makes more sense?
> ---
> drivers/vhost/Kconfig | 10 ++++++++
> drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
> drivers/vhost/vhost.h | 17 +++++++++++++-
> include/uapi/linux/vhost.h | 5 ++++
> 4 files changed, 86 insertions(+), 1 deletion(-)
>
> Changes since v2:
> - fixed typos in Kconfig description
> - renamed vq->legacy_big_endian to vq->legacy_is_little_endian
> - vq->legacy_is_little_endian reset to default in vhost_vq_reset()
> - dropped VHOST_F_SET_ENDIAN_LEGACY feature
> - dropped struct vhost_vring_endian from the user API (re-use
> struct vhost_vring_state instead)
> - added VHOST_GET_VRING_ENDIAN_LEGACY ioctl
> - introduced more helpers and stubs to avoid polluting the code with ifdefs
>
>
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index 017a1e8..0aec88c 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -32,3 +32,13 @@ config VHOST
> ---help---
> This option is selected by any driver which needs to access
> the core of vhost.
> +
> +config VHOST_SET_ENDIAN_LEGACY
> + bool "Cross-endian support for host kernel accelerator"
> + default n
> + ---help---
> + This option allows vhost to support guests with a different byte
> + ordering from host. It is disabled by default since it adds overhead
> + and it is only needed by a few platforms (powerpc and arm).
> +
> + If unsure, say "N".
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 2ee2826..3529a3c 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -199,6 +199,7 @@ static void vhost_vq_reset(struct vhost_dev *dev,
> vq->call = NULL;
> vq->log_ctx = NULL;
> vq->memory = NULL;
> + vq->legacy_is_little_endian = virtio_legacy_is_little_endian();
> }
>
> static int vhost_worker(void *data)
> @@ -630,6 +631,54 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
> return 0;
> }
>
> +#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + struct vhost_vring_state s;
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
EINVAL probably makes more sense? But I'm not sure this
is helpful: one can set VIRTIO_F_VERSION_1 afterwards,
and your patch does not seem to detect this.
> +
> + if (copy_from_user(&s, argp, sizeof(s)))
> + return -EFAULT;
> +
> + vq->legacy_is_little_endian = !!s.num;
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + struct vhost_vring_state s = {
> + .index = idx,
> + .num = vq->legacy_is_little_endian
> + };
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
> +
> + if (copy_to_user(argp, &s, sizeof(s)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +#else
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + return 0;
> +}
Should be -ENOIOCTLCMD?
> +#endif /* CONFIG_VHOST_SET_ENDIAN_LEGACY */
> +
> long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
> {
> struct file *eventfp, *filep = NULL;
> @@ -806,6 +855,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
> } else
> filep = eventfp;
> break;
> + case VHOST_SET_VRING_ENDIAN_LEGACY:
> + r = vhost_set_vring_endian_legacy(vq, argp);
> + break;
> + case VHOST_GET_VRING_ENDIAN_LEGACY:
> + r = vhost_get_vring_endian_legacy(vq, idx, argp);
> + break;
> default:
> r = -ENOIOCTLCMD;
> }
I think we also want to forbid this with a running backend.
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 4e9a186..981ba06 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -106,6 +106,9 @@ struct vhost_virtqueue {
> /* Log write descriptors */
> void __user *log_base;
> struct vhost_log *log;
> +
> + /* We need to know the device endianness with legacy virtio. */
> + bool legacy_is_little_endian;
> };
>
> struct vhost_dev {
> @@ -173,11 +176,23 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
> return vq->acked_features & (1ULL << bit);
> }
>
> +#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
> +static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
> +{
> + return vq->legacy_is_little_endian;
> +}
> +#else
> +static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
> +{
> + return virtio_legacy_is_little_endian();
> +}
> +#endif
> +
> static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> {
> if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> return true;
> - return virtio_legacy_is_little_endian();
> + return vhost_legacy_is_little_endian(vq);
> }
>
> /* Memory accessors */
> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> index bb6a5b4..1b01a72 100644
> --- a/include/uapi/linux/vhost.h
> +++ b/include/uapi/linux/vhost.h
> @@ -103,6 +103,11 @@ struct vhost_memory {
> /* Get accessor: reads index, writes value in num */
> #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
>
> +/* Set endianness for the ring (legacy virtio only) */
> +/* num is 0 for big endian, other values mean little endian */
I'd prefer 0 and 1, return EINVAL on other values.
> +#define VHOST_SET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
> +#define VHOST_GET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
> +
> /* The following ioctls use eventfd file descriptors to signal and poll
> * for events. */
>
^ permalink raw reply
* Re: [PATCH v3 0/7] vhost: support for cross endian guests
From: Michael S. Tsirkin @ 2015-04-07 15:55 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150407120929.4213.8225.stgit-to6p26YowclJmDnNpxttO7KMsZMIf1jtdfLczzV0R5oAvxtiuMwx3w@public.gmane.org>
On Tue, Apr 07, 2015 at 02:09:29PM +0200, Greg Kurz wrote:
> Hi,
>
> This patchset allows vhost to be used with legacy virtio when guest and host
> have a different endianness.
>
> Patches 1-6 remain the same as the previous post. Patch 7 was heavily changed
> according to MST's comments.
This still doesn't actually work, right?
tun and macvtap need new ioctls too ...
> ---
>
> Greg Kurz (7):
> virtio: introduce virtio_is_little_endian() helper
> tun: add tun_is_little_endian() helper
> macvtap: introduce macvtap_is_little_endian() helper
> vringh: introduce vringh_is_little_endian() helper
> vhost: introduce vhost_is_little_endian() helper
> virtio: add explicit big-endian support to memory accessors
> vhost: feature to set the vring endianness
>
>
> drivers/net/macvtap.c | 11 ++++++--
> drivers/net/tun.c | 11 ++++++--
> drivers/vhost/Kconfig | 10 +++++++
> drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++
> drivers/vhost/vhost.h | 34 +++++++++++++++++++----
> include/linux/virtio_byteorder.h | 24 ++++++++++-------
> include/linux/virtio_config.h | 19 +++++++++----
> include/linux/vringh.h | 19 +++++++++----
> include/uapi/linux/vhost.h | 5 +++
> 9 files changed, 156 insertions(+), 32 deletions(-)
>
> --
> Greg
^ permalink raw reply
* Re: [PATCH v3 6/7] virtio: add explicit big-endian support to memory accessors
From: Michael S. Tsirkin @ 2015-04-07 15:56 UTC (permalink / raw)
To: Greg Kurz; +Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407121533.4213.46434.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
On Tue, Apr 07, 2015 at 02:15:52PM +0200, Greg Kurz wrote:
> The current memory accessors logic is:
> - little endian if little_endian
> - native endian (i.e. no byteswap) if !little_endian
>
> If we want to fully support cross-endian vhost, we also need to be
> able to convert to big endian.
>
> Instead of changing the little_endian argument to some 3-value enum, this
> patch changes the logic to:
> - little endian if little_endian
> - big endian if !little_endian
>
> The native endian case is handled by all users with a trivial helper. This
> patch doesn't change any functionality, nor it does add overhead.
>
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/net/macvtap.c | 4 +++-
> drivers/net/tun.c | 4 +++-
> drivers/vhost/vhost.h | 4 +++-
> include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
> include/linux/virtio_config.h | 4 +++-
> include/linux/vringh.h | 4 +++-
> 6 files changed, 29 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index a2f2958..0a03a66 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -51,7 +51,9 @@ struct macvtap_queue {
>
> static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
> {
> - return q->flags & MACVTAP_VNET_LE;
> + if (q->flags & MACVTAP_VNET_LE)
> + return true;
> + return virtio_legacy_is_little_endian();
> }
>
> static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
Hmm I'm not sure how well this will work once you
actually make it dynamic.
Remains to be seen.
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 3c3d6c0..053f9b6 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -208,7 +208,9 @@ struct tun_struct {
>
> static inline bool tun_is_little_endian(struct tun_struct *tun)
> {
> - return tun->flags & TUN_VNET_LE;
> + if (tun->flags & TUN_VNET_LE)
> + return true;
> + return virtio_legacy_is_little_endian();
> }
>
> static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 6a49960..4e9a186 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -175,7 +175,9 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
>
> static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> {
> - return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return true;
> + return virtio_legacy_is_little_endian();
> }
>
> /* Memory accessors */
> diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h
> index 51865d0..ce63a2c 100644
> --- a/include/linux/virtio_byteorder.h
> +++ b/include/linux/virtio_byteorder.h
> @@ -3,17 +3,21 @@
> #include <linux/types.h>
> #include <uapi/linux/virtio_types.h>
>
> -/*
> - * Low-level memory accessors for handling virtio in modern little endian and in
> - * compatibility native endian format.
> - */
> +static inline bool virtio_legacy_is_little_endian(void)
> +{
> +#ifdef __LITTLE_ENDIAN
> + return true;
> +#else
> + return false;
> +#endif
> +}
>
> static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
> {
> if (little_endian)
> return le16_to_cpu((__force __le16)val);
> else
> - return (__force u16)val;
> + return be16_to_cpu((__force __be16)val);
> }
>
> static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
> @@ -21,7 +25,7 @@ static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
> if (little_endian)
> return (__force __virtio16)cpu_to_le16(val);
> else
> - return (__force __virtio16)val;
> + return (__force __virtio16)cpu_to_be16(val);
> }
>
> static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
> @@ -29,7 +33,7 @@ static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
> if (little_endian)
> return le32_to_cpu((__force __le32)val);
> else
> - return (__force u32)val;
> + return be32_to_cpu((__force __be32)val);
> }
>
> static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
> @@ -37,7 +41,7 @@ static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
> if (little_endian)
> return (__force __virtio32)cpu_to_le32(val);
> else
> - return (__force __virtio32)val;
> + return (__force __virtio32)cpu_to_be32(val);
> }
>
> static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
> @@ -45,7 +49,7 @@ static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
> if (little_endian)
> return le64_to_cpu((__force __le64)val);
> else
> - return (__force u64)val;
> + return be64_to_cpu((__force __be64)val);
> }
>
> static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
> @@ -53,7 +57,7 @@ static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
> if (little_endian)
> return (__force __virtio64)cpu_to_le64(val);
> else
> - return (__force __virtio64)val;
> + return (__force __virtio64)cpu_to_be64(val);
> }
>
> #endif /* _LINUX_VIRTIO_BYTEORDER */
> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index bd1a582..36a6daa 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -207,7 +207,9 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
>
> static inline bool virtio_is_little_endian(struct virtio_device *vdev)
> {
> - return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
> + if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
> + return true;
> + return virtio_legacy_is_little_endian();
> }
>
> /* Memory accessors */
> diff --git a/include/linux/vringh.h b/include/linux/vringh.h
> index 3ed62ef..d786c2d 100644
> --- a/include/linux/vringh.h
> +++ b/include/linux/vringh.h
> @@ -228,7 +228,9 @@ static inline void vringh_notify(struct vringh *vrh)
>
> static inline bool vringh_is_little_endian(const struct vringh *vrh)
> {
> - return vrh->little_endian;
> + if (vrh->little_endian)
> + return true;
> + return virtio_legacy_is_little_endian();
> }
>
> static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
^ permalink raw reply
* Re: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
From: Maxime Coquelin @ 2015-04-07 16:05 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Uwe Kleine-König, Andreas Färber, Geert Uytterhoeven,
Rob Herring, Philipp Zabel, Linus Walleij, Arnd Bergmann,
Stefan Agner, Peter Meerwald, Paul Bolle, Peter Hurley,
Chanwoo Choi, Russell King, Daniel Lezcano, Jonathan Corbet,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <CAHp75VfRpwH3gw=EX816Bd8QnGSVzPg8+OWppqEKp2H_vCzRXw@mail.gmail.com>
2015-04-04 0:04 GMT+02:00 Andy Shevchenko <andy.shevchenko@gmail.com>:
> On Fri, Apr 3, 2015 at 8:01 PM, Maxime Coquelin
> <mcoquelin.stm32@gmail.com> wrote:
>> This drivers adds support to the STM32 USART controller, which is a
>> standard serial driver.
>>
>
> Few minor comments.
>
>> Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>> drivers/tty/serial/Kconfig | 17 +
>> drivers/tty/serial/Makefile | 1 +
>> drivers/tty/serial/stm32-usart.c | 736 +++++++++++++++++++++++++++++++++++++++
>> include/uapi/linux/serial_core.h | 3 +
>> 4 files changed, 757 insertions(+)
>> create mode 100644 drivers/tty/serial/stm32-usart.c
>>
>> diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
>> new file mode 100644
>> index 0000000..61e0e19
>> --- /dev/null
>> +++ b/drivers/tty/serial/stm32-usart.c
>> @@ -0,0 +1,736 @@
...
>> +
>> +static unsigned int stm32_get_mctrl(struct uart_port *port)
>> +{
>> + /* This routine is used to get signals of: DCD, DSR, RI, and CTS */
>> + return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
>> +}
>> +
>> +/* Transmit stop */
>> +static void stm32_stop_tx(struct uart_port *port)
>> +{
>> + stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE);
>> +}
>> +
>> +
>
> Unneeded empty line.
Right, will be removed.
>
...
>> +
>> +static int stm32_startup(struct uart_port *port)
>> +{
>> + const char *name = to_platform_device(port->dev)->name;
>> + u32 val;
>> +
>> + if (request_irq(port->irq, stm32_interrupt, IRQF_NO_SUSPEND,
>> + name, port)) {
>
> I think you have to propogate returned value, thus
> ret = request_irq();
> if (ret < 0)
> return ret;
Exact, I will fix this.
>
...
>> +
>> +static const char *stm32_type(struct uart_port *port)
>> +{
>> + return (port->type == PORT_STM32) ? DRIVER_NAME : NULL;
>> +}
>> +
>> +static void stm32_release_port(struct uart_port *port)
>> +{
>> +}
>
> Doesn't core handle NULL-functions? If it does, remove such from the driver.
No it does not.
>
>> +
>> +static int stm32_request_port(struct uart_port *port)
>> +{
>> + return 0;
>> +}
>
> Ditto.
Ditto.
Thanks for the review,
Maxime
>
>
>
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v3 0/7] vhost: support for cross endian guests
From: Greg Kurz @ 2015-04-07 16:08 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Rusty Russell, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150407175443-mutt-send-email-mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Tue, 7 Apr 2015 17:55:08 +0200
"Michael S. Tsirkin" <mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Tue, Apr 07, 2015 at 02:09:29PM +0200, Greg Kurz wrote:
> > Hi,
> >
> > This patchset allows vhost to be used with legacy virtio when guest and host
> > have a different endianness.
> >
> > Patches 1-6 remain the same as the previous post. Patch 7 was heavily changed
> > according to MST's comments.
>
> This still doesn't actually work, right?
> tun and macvtap need new ioctls too ...
>
Yes they do. I already have a patch but I wasn't sure if I should send it
along this series... Since it looks like there will be a v4, I'll add the
tun/macvtap patch.
Thanks.
--
Greg
> > ---
> >
> > Greg Kurz (7):
> > virtio: introduce virtio_is_little_endian() helper
> > tun: add tun_is_little_endian() helper
> > macvtap: introduce macvtap_is_little_endian() helper
> > vringh: introduce vringh_is_little_endian() helper
> > vhost: introduce vhost_is_little_endian() helper
> > virtio: add explicit big-endian support to memory accessors
> > vhost: feature to set the vring endianness
> >
> >
> > drivers/net/macvtap.c | 11 ++++++--
> > drivers/net/tun.c | 11 ++++++--
> > drivers/vhost/Kconfig | 10 +++++++
> > drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++
> > drivers/vhost/vhost.h | 34 +++++++++++++++++++----
> > include/linux/virtio_byteorder.h | 24 ++++++++++-------
> > include/linux/virtio_config.h | 19 +++++++++----
> > include/linux/vringh.h | 19 +++++++++----
> > include/uapi/linux/vhost.h | 5 +++
> > 9 files changed, 156 insertions(+), 32 deletions(-)
> >
> > --
> > Greg
>
^ permalink raw reply
* Re: [PATCH v3 7/7] vhost: feature to set the vring endianness
From: Michael S. Tsirkin @ 2015-04-07 16:11 UTC (permalink / raw)
To: Greg Kurz; +Cc: Rusty Russell, linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150407121557.4213.95569.stgit@bahia.lab.toulouse-stg.fr.ibm.com>
On Tue, Apr 07, 2015 at 02:19:31PM +0200, Greg Kurz wrote:
> This patch brings cross-endian support to vhost when used to implement
> legacy virtio devices. Since it is a relatively rare situation, the
> feature availability is controlled by a kernel config option (not set
> by default).
>
> The ioctls introduced by this patch are for legacy only: virtio 1.0
> devices are returned EPERM.
>
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/vhost/Kconfig | 10 ++++++++
> drivers/vhost/vhost.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
> drivers/vhost/vhost.h | 17 +++++++++++++-
> include/uapi/linux/vhost.h | 5 ++++
> 4 files changed, 86 insertions(+), 1 deletion(-)
>
> Changes since v2:
> - fixed typos in Kconfig description
> - renamed vq->legacy_big_endian to vq->legacy_is_little_endian
> - vq->legacy_is_little_endian reset to default in vhost_vq_reset()
> - dropped VHOST_F_SET_ENDIAN_LEGACY feature
> - dropped struct vhost_vring_endian from the user API (re-use
> struct vhost_vring_state instead)
> - added VHOST_GET_VRING_ENDIAN_LEGACY ioctl
> - introduced more helpers and stubs to avoid polluting the code with ifdefs
>
>
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index 017a1e8..0aec88c 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -32,3 +32,13 @@ config VHOST
> ---help---
> This option is selected by any driver which needs to access
> the core of vhost.
> +
> +config VHOST_SET_ENDIAN_LEGACY
> + bool "Cross-endian support for host kernel accelerator"
> + default n
> + ---help---
> + This option allows vhost to support guests with a different byte
> + ordering from host. It is disabled by default since it adds overhead
> + and it is only needed by a few platforms (powerpc and arm).
> +
> + If unsure, say "N".
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 2ee2826..3529a3c 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -199,6 +199,7 @@ static void vhost_vq_reset(struct vhost_dev *dev,
> vq->call = NULL;
> vq->log_ctx = NULL;
> vq->memory = NULL;
> + vq->legacy_is_little_endian = virtio_legacy_is_little_endian();
> }
>
> static int vhost_worker(void *data)
> @@ -630,6 +631,54 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
> return 0;
> }
>
> +#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + struct vhost_vring_state s;
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
> +
> + if (copy_from_user(&s, argp, sizeof(s)))
> + return -EFAULT;
> +
> + vq->legacy_is_little_endian = !!s.num;
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + struct vhost_vring_state s = {
> + .index = idx,
> + .num = vq->legacy_is_little_endian
> + };
> +
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + return -EPERM;
> +
> + if (copy_to_user(argp, &s, sizeof(s)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +#else
> +static long vhost_set_vring_endian_legacy(struct vhost_virtqueue *vq,
> + void __user *argp)
> +{
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian_legacy(struct vhost_virtqueue *vq,
> + u32 idx,
> + void __user *argp)
> +{
> + return 0;
> +}
> +#endif /* CONFIG_VHOST_SET_ENDIAN_LEGACY */
> +
> long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
> {
> struct file *eventfp, *filep = NULL;
> @@ -806,6 +855,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
> } else
> filep = eventfp;
> break;
> + case VHOST_SET_VRING_ENDIAN_LEGACY:
> + r = vhost_set_vring_endian_legacy(vq, argp);
> + break;
> + case VHOST_GET_VRING_ENDIAN_LEGACY:
> + r = vhost_get_vring_endian_legacy(vq, idx, argp);
> + break;
> default:
> r = -ENOIOCTLCMD;
> }
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 4e9a186..981ba06 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -106,6 +106,9 @@ struct vhost_virtqueue {
> /* Log write descriptors */
> void __user *log_base;
> struct vhost_log *log;
> +
> + /* We need to know the device endianness with legacy virtio. */
> + bool legacy_is_little_endian;
> };
>
> struct vhost_dev {
> @@ -173,11 +176,23 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
> return vq->acked_features & (1ULL << bit);
> }
>
> +#ifdef CONFIG_VHOST_SET_ENDIAN_LEGACY
> +static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
> +{
> + return vq->legacy_is_little_endian;
> +}
> +#else
> +static inline bool vhost_legacy_is_little_endian(struct vhost_virtqueue *vq)
> +{
> + return virtio_legacy_is_little_endian();
> +}
> +#endif
> +
> static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> {
> if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> return true;
> - return virtio_legacy_is_little_endian();
> + return vhost_legacy_is_little_endian(vq);
> }
>
> /* Memory accessors */
> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> index bb6a5b4..1b01a72 100644
> --- a/include/uapi/linux/vhost.h
> +++ b/include/uapi/linux/vhost.h
> @@ -103,6 +103,11 @@ struct vhost_memory {
> /* Get accessor: reads index, writes value in num */
> #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
>
> +/* Set endianness for the ring (legacy virtio only) */
> +/* num is 0 for big endian, other values mean little endian */
> +#define VHOST_SET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
> +#define VHOST_GET_VRING_ENDIAN_LEGACY _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
> +
> /* The following ioctls use eventfd file descriptors to signal and poll
> * for events. */
>
So if the config feature is enabled, you actually check two
things: 1. feature 2. ioctl
Why not override is_le when we set VIRTIO_F_VERSION_1?
I guess you are worried that setting a value and not being
able to read it back is ugly. We can add a flag to track
it though. So here's an idea
I would probably rename to G/SET_BIG_ENDIAN then it's obvious
it's legacy. And just document that it's ignored with
VIRTIO_F_VERSION_1.
make sure it's not changed when ring is running
simply set vq->is_le correctly when we start/stop the device
vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) ||
!vq->user_be;
static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
{
return vq->is_le;
}
--
MST
^ permalink raw reply
* [PATCH v6 00/15] Add support to STMicroelectronics STM32 family
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ, afaerber-l3A5Bk7waGM,
geert-Td1EMuHUCqxL1ZNQvxDV9g, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan-XLVq0VzYD2Y,
pmeerw-jW+XmwGofnusTnJN9+BGXg, pebolle-IWqWACnzNjzz+pZb47iToQ,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w,
cw00.choi-Sze3O3UU22JBDgjK7y7TUQ, Russell King, Daniel Lezcano,
joe-6d6DIl74uiNBDgjK7y7TUQ
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Antti Palosaari, Tejun Heo, Will Deacon, Nikolay Borisov,
Rusty Russell, Kees Cook, Michal Marek,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-arch-u79uwXL29TZNg+MwTxZMZA
This sixth round adds minor fixes to USART driver, and adds some Acks.
STM32 MCUs are Cortex-M CPU, used in various applications (consumer
electronics, industrial applications, hobbyists...).
Datasheets, user and programming manuals are publicly available on
STMicroelectronics website.
With this series applied, the STM32F419 Discovery can boot succesfully.
Changes since v5:
-----------------
- Change st,hw-flow-ctrl property to auto-flow-control (Rob)
- Constify stm32_uart_ops (Joe)
- Propagate request_irq error in USART driver (Andy)
- Applies Acked-by and Reviewed-by (Rob, Peter)
Changes since v4:
-----------------
- Cosmetic changes in USART driver (Andy)
- Apply Acks on reset driver & bindings (Philipp & Rob)
Changes since v3:
-----------------
- Fix and simplify error path in ARMv7-M Systick driver (Daniel)
- Improve reset bindings documentation (Philipp)
- Fix trailing lines anf typos in reset driver & doc (Philipp & Chanwoo)
- Fix MODULE_LICENCE in USART driver (Paul)
- Refactor USART baudrate calculation (Peter & Andy)
- Fix error path in USART init (Peter & Russell)
- Fix HW flow control in USART driver (Peter)
- Fix serial port type number to unused one (Peter)
- Applies Chanwoo's Tested-by on the series
Changes since v2:
-----------------
- Remove pinctrl driver from the series.
- Remove reset_controller_of_init(), and reset the timers in the bootloader
- Add HW flow contrl property for serial driver
- Lots of changes in the DTS file, as per Andreas recommendations
- Some Kconfig clean-ups
- Adapt the config to be compatible with Andreas' bootwrapper, except UART port.
- Various fixes in documentation
Changes since v1:
-----------------
- Move bindings documentation in their own patches (Andreas)
- Rename ARM System timer to armv7m-systick (Rob)
- Add clock-frequency property handling in armv7m-systick (Rob)
- Re-factor the reset controllers into a single controller (Philipp)
- Add kerneldoc to reset_controller_of_init (Philipp)
- Add named constants in include/dt-bindings/reset/ (Philipp)
- Make pinctrl driver to depend on ARCH_STM32 or COMPILE_TEST (Geert)
- Introduce CPUV7M_NUM_IRQ config flag to indicate the number of interrupts
supported by the MCU, in order to limit memory waste in vectors' table (Uwe)
Maxime Coquelin (15):
scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP
Kernel
ARM: ARMv7-M: Enlarge vector table up to 256 entries
dt-bindings: Document the ARM System timer bindings
clocksource/drivers: Add ARM System timer driver
dt-bindings: Document the STM32 reset bindings
drivers: reset: Add STM32 reset driver
dt-bindings: Document the STM32 timer bindings
clockevents/drivers: Add STM32 Timer driver
dt-bindings: Document the STM32 USART bindings
serial: stm32-usart: Add STM32 USART Driver
ARM: Add STM32 family machine
ARM: dts: Add ARM System timer as clockevent in armv7m
ARM: dts: Introduce STM32F429 MCU
ARM: configs: Add STM32 defconfig
MAINTAINERS: Add entry for STM32 MCUs
Documentation/arm/stm32/overview.txt | 32 +
Documentation/arm/stm32/stm32f429-overview.txt | 22 +
.../devicetree/bindings/arm/armv7m_systick.txt | 26 +
.../devicetree/bindings/reset/st,stm32-rcc.txt | 107 +++
.../devicetree/bindings/serial/st,stm32-usart.txt | 32 +
.../devicetree/bindings/timer/st,stm32-timer.txt | 22 +
MAINTAINERS | 8 +
arch/arm/Kconfig | 18 +
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/armv7-m.dtsi | 6 +
arch/arm/boot/dts/stm32f429-disco.dts | 71 ++
arch/arm/boot/dts/stm32f429.dtsi | 226 +++++++
arch/arm/configs/stm32_defconfig | 71 ++
arch/arm/kernel/entry-v7m.S | 13 +-
arch/arm/mach-stm32/Makefile | 1 +
arch/arm/mach-stm32/Makefile.boot | 3 +
arch/arm/mach-stm32/board-dt.c | 19 +
arch/arm/mm/Kconfig | 15 +
drivers/clocksource/Kconfig | 15 +
drivers/clocksource/Makefile | 2 +
drivers/clocksource/armv7m_systick.c | 79 +++
drivers/clocksource/timer-stm32.c | 184 ++++++
drivers/reset/Makefile | 1 +
drivers/reset/reset-stm32.c | 124 ++++
drivers/tty/serial/Kconfig | 17 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/stm32-usart.c | 735 +++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
scripts/link-vmlinux.sh | 2 +-
30 files changed, 1852 insertions(+), 5 deletions(-)
create mode 100644 Documentation/arm/stm32/overview.txt
create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt
create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
create mode 100644 arch/arm/configs/stm32_defconfig
create mode 100644 arch/arm/mach-stm32/Makefile
create mode 100644 arch/arm/mach-stm32/Makefile.boot
create mode 100644 arch/arm/mach-stm32/board-dt.c
create mode 100644 drivers/clocksource/armv7m_systick.c
create mode 100644 drivers/clocksource/timer-stm32.c
create mode 100644 drivers/reset/reset-stm32.c
create mode 100644 drivers/tty/serial/stm32-usart.c
--
1.9.1
^ permalink raw reply
* [PATCH v6 01/15] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano, joe
Cc: Mark Rutland, linux-doc, Will Deacon, Nikolay Borisov, linux-api,
Jiri Slaby, linux-arch, Jonathan Corbet, Mauro Carvalho Chehab,
Antti Palosaari, linux-serial, devicetree, Kees Cook, Pawel Moll,
Ian Campbell, Rusty Russell, linux-gpio, Thomas Gleixner,
linux-arm-kernel, Michal Marek, Greg Kroah-Hartman, linux-kernel,
mcoquelin.stm32, Kumar Gala, Tejun Heo, Andrew Morton
In-Reply-To: <1428424234-28572-1-git-send-email-mcoquelin.stm32@gmail.com>
When Kernel is executed in place from ROM, the symbol addresses can be
lower than the page offset.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
scripts/link-vmlinux.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 86a4fe7..b055d9d 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -82,7 +82,7 @@ kallsyms()
kallsymopt="${kallsymopt} --all-symbols"
fi
- if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
+ if [ -n "${CONFIG_ARM}" ] && [ -z "${CONFIG_XIP_KERNEL}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
fi
--
1.9.1
^ permalink raw reply related
* [PATCH v6 02/15] ARM: ARMv7-M: Enlarge vector table up to 256 entries
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano, joe
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Antti Palosaari, Tejun Heo, Will Deacon, Nikolay Borisov,
Rusty Russell, Kees Cook, Michal Marek, linux-doc,
linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial, linux-arch
In-Reply-To: <1428424234-28572-1-git-send-email-mcoquelin.stm32@gmail.com>
From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
So the number of entries in vectors table is up to 256.
This patch adds a new config flag to specify the number of external interrupts.
Some ifdeferies are added in order to respect the natural alignment without
wasting too much space on smaller systems.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Stefan Agner <stefan@agner.ch>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
arch/arm/kernel/entry-v7m.S | 13 +++++++++----
arch/arm/mm/Kconfig | 15 +++++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 8944f49..b6c8bb9 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -117,9 +117,14 @@ ENTRY(__switch_to)
ENDPROC(__switch_to)
.data
- .align 8
+#if CONFIG_CPU_V7M_NUM_IRQ <= 112
+ .align 9
+#else
+ .align 10
+#endif
+
/*
- * Vector table (64 words => 256 bytes natural alignment)
+ * Vector table (Natural alignment need to be ensured)
*/
ENTRY(vector_table)
.long 0 @ 0 - Reset stack pointer
@@ -138,6 +143,6 @@ ENTRY(vector_table)
.long __invalid_entry @ 13 - Reserved
.long __pendsv_entry @ 14 - PendSV
.long __invalid_entry @ 15 - SysTick
- .rept 64 - 16
- .long __irq_entry @ 16..64 - External Interrupts
+ .rept CONFIG_CPU_V7M_NUM_IRQ
+ .long __irq_entry @ External Interrupts
.endr
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 9b4f29e..aec53b4 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -604,6 +604,21 @@ config CPU_USE_DOMAINS
This option enables or disables the use of domain switching
via the set_fs() function.
+config CPU_V7M_NUM_IRQ
+ int "Number of external interrupts connected to the NVIC"
+ depends on CPU_V7M
+ default 90 if ARCH_STM32
+ default 38 if ARCH_EFM32
+ default 240
+ help
+ This option indicates the number of interrupts connected to the NVIC.
+ The value can be larger than the real number of interrupts supported
+ by the system, but must not be lower.
+ The default value is 240, corresponding to the maximum number of
+ interrupts supported by the NVIC on Cortex-M family.
+
+ If unsure, keep default value.
+
#
# CPU supports 36-bit I/O
#
--
1.9.1
^ permalink raw reply related
* [PATCH v6 03/15] dt-bindings: Document the ARM System timer bindings
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ, afaerber-l3A5Bk7waGM,
geert-Td1EMuHUCqxL1ZNQvxDV9g, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan-XLVq0VzYD2Y,
pmeerw-jW+XmwGofnusTnJN9+BGXg, pebolle-IWqWACnzNjzz+pZb47iToQ,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w,
cw00.choi-Sze3O3UU22JBDgjK7y7TUQ, Russell King, Daniel Lezcano,
joe-6d6DIl74uiNBDgjK7y7TUQ
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Antti Palosaari, Tejun Heo, Will Deacon, Nikolay Borisov,
Rusty Russell, Kees Cook, Michal Marek,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-arch-u79uwXL29TZNg+MwTxZMZA
In-Reply-To: <1428424234-28572-1-git-send-email-mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This adds documentation of device tree bindings for the
ARM System timer.
Tested-by: Chanwoo Choi <cw00.choi-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/arm/armv7m_systick.txt | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
diff --git a/Documentation/devicetree/bindings/arm/armv7m_systick.txt b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
new file mode 100644
index 0000000..7cf4a24
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
@@ -0,0 +1,26 @@
+* ARMv7M System Timer
+
+ARMv7-M includes a system timer, known as SysTick. Current driver only
+implements the clocksource feature.
+
+Required properties:
+- compatible : Should be "arm,armv7m-systick"
+- reg : The address range of the timer
+
+Required clocking property, have to be one of:
+- clocks : The input clock of the timer
+- clock-frequency : The rate in HZ in input of the ARM SysTick
+
+Examples:
+
+systick: timer@e000e010 {
+ compatible = "arm,armv7m-systick";
+ reg = <0xe000e010 0x10>;
+ clocks = <&clk_systick>;
+};
+
+systick: timer@e000e010 {
+ compatible = "arm,armv7m-systick";
+ reg = <0xe000e010 0x10>;
+ clock-frequency = <90000000>;
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v6 04/15] clocksource/drivers: Add ARM System timer driver
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano, joe
Cc: Mark Rutland, linux-doc, Will Deacon, Nikolay Borisov, linux-api,
Jiri Slaby, linux-arch, Jonathan Corbet, Mauro Carvalho Chehab,
Antti Palosaari, linux-serial, devicetree, Kees Cook, Pawel Moll,
Ian Campbell, Rusty Russell, linux-gpio, Thomas Gleixner,
linux-arm-kernel, Michal Marek, Greg Kroah-Hartman, linux-kernel,
mcoquelin.stm32, Kumar Gala, Tejun Heo, Andrew Morton
In-Reply-To: <1428424234-28572-1-git-send-email-mcoquelin.stm32@gmail.com>
This patch adds clocksource support for ARMv7-M's System timer,
also known as SysTick.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
drivers/clocksource/Kconfig | 7 ++++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/armv7m_systick.c | 79 ++++++++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+)
create mode 100644 drivers/clocksource/armv7m_systick.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 1c2506f..b82e58b 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -134,6 +134,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
Use ARM global timer clock source as sched_clock
+config ARMV7M_SYSTICK
+ bool
+ select CLKSRC_OF if OF
+ select CLKSRC_MMIO
+ help
+ This options enables support for the ARMv7M system timer unit
+
config ATMEL_PIT
select CLKSRC_OF if OF
def_bool SOC_AT91SAM9 || SOC_SAMA5
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 752d5c7..1c9a643 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
+obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
diff --git a/drivers/clocksource/armv7m_systick.c b/drivers/clocksource/armv7m_systick.c
new file mode 100644
index 0000000..addfd2c
--- /dev/null
+++ b/drivers/clocksource/armv7m_systick.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/bitops.h>
+
+#define SYST_CSR 0x00
+#define SYST_RVR 0x04
+#define SYST_CVR 0x08
+#define SYST_CALIB 0x0c
+
+#define SYST_CSR_ENABLE BIT(0)
+
+#define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF
+
+static void __init system_timer_of_register(struct device_node *np)
+{
+ struct clk *clk = NULL;
+ void __iomem *base;
+ u32 rate;
+ int ret;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("system-timer: invalid base address\n");
+ return;
+ }
+
+ ret = of_property_read_u32(np, "clock-frequency", &rate);
+ if (ret) {
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk))
+ goto out_unmap;
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto out_clk_put;
+
+ rate = clk_get_rate(clk);
+ if (!rate)
+ goto out_clk_disable;
+ }
+
+ writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR);
+ writel_relaxed(SYST_CSR_ENABLE, base + SYST_CSR);
+
+ ret = clocksource_mmio_init(base + SYST_CVR, "arm_system_timer", rate,
+ 200, 24, clocksource_mmio_readl_down);
+ if (ret) {
+ pr_err("failed to init clocksource (%d)\n", ret);
+ if (clk)
+ goto out_clk_disable;
+ else
+ goto out_unmap;
+ }
+
+ pr_info("ARM System timer initialized as clocksource\n");
+
+ return;
+
+out_clk_disable:
+ clk_disable_unprepare(clk);
+out_clk_put:
+ clk_put(clk);
+out_unmap:
+ iounmap(base);
+ pr_warn("ARM System timer register failed (%d)\n", ret);
+}
+
+CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick",
+ system_timer_of_register);
--
1.9.1
^ permalink raw reply related
* [PATCH v6 05/15] dt-bindings: Document the STM32 reset bindings
From: Maxime Coquelin @ 2015-04-07 16:30 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano, joe
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Antti Palosaari, Tejun Heo, Will Deacon, Nikolay Borisov,
Rusty Russell, Kees Cook, Michal Marek, linux-doc,
linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial, linux-arch
In-Reply-To: <1428424234-28572-1-git-send-email-mcoquelin.stm32@gmail.com>
This adds documentation of device tree bindings for the
STM32 reset controller.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
.../devicetree/bindings/reset/st,stm32-rcc.txt | 107 +++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
diff --git a/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt b/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
new file mode 100644
index 0000000..c1b0f8d
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
@@ -0,0 +1,107 @@
+STMicroelectronics STM32 Peripheral Reset Controller
+====================================================
+
+The RCC IP is both a reset and a clock controller. This documentation only
+documents the reset part.
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "st,stm32-rcc"
+- reg: should be register base and length as documented in the
+ datasheet
+- #reset-cells: 1, see below
+
+example:
+
+rcc: reset@40023800 {
+ #reset-cells = <1>;
+ compatible = "st,stm32-rcc";
+ reg = <0x40023800 0x400>;
+};
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+For example, for CRC reset:
+ crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140
+
+example:
+
+ timer2 {
+ resets = <&rcc 256>;
+ };
+
+List of valid indices for STM32F429:
+ - gpioa: 128
+ - gpiob: 129
+ - gpioc: 130
+ - gpiod: 131
+ - gpioe: 132
+ - gpiof: 133
+ - gpiog: 134
+ - gpioh: 135
+ - gpioi: 136
+ - gpioj: 137
+ - gpiok: 138
+ - crc: 140
+ - dma1: 149
+ - dma2: 150
+ - dma2d: 151
+ - ethmac: 153
+ - otghs: 157
+ - dcmi: 160
+ - cryp: 164
+ - hash: 165
+ - rng: 166
+ - otgfs: 167
+ - fmc: 192
+ - tim2: 256
+ - tim3: 257
+ - tim4: 258
+ - tim5: 259
+ - tim6: 260
+ - tim7: 261
+ - tim12: 262
+ - tim13: 263
+ - tim14: 264
+ - wwdg: 267
+ - spi2: 270
+ - spi3: 271
+ - uart2: 273
+ - uart3: 274
+ - uart4: 275
+ - uart5: 276
+ - i2c1: 277
+ - i2c2: 278
+ - i2c3: 279
+ - can1: 281
+ - can2: 282
+ - pwr: 284
+ - dac: 285
+ - uart7: 286
+ - uart8: 287
+ - tim1: 288
+ - tim8: 289
+ - usart1: 292
+ - usart6: 293
+ - adc: 296
+ - sdio: 299
+ - spi1: 300
+ - spi4: 301
+ - syscfg: 302
+ - tim9: 304
+ - tim10: 305
+ - tim11: 306
+ - spi5: 308
+ - spi6: 309
+ - sai1: 310
+ - ltdc: 314
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox