Compare commits
10 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1126cbfcae | ||
|
|
8d859c10ee | ||
|
|
a9eb426b07 | ||
|
|
2334838f4e | ||
|
|
3c3686c2d6 | ||
|
|
659a9b49ea | ||
|
|
928ca23fa0 | ||
|
|
e0018c4e82 | ||
|
|
5e6740fccc | ||
|
|
d5e266a6ac |
11 changed files with 601 additions and 230 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -6,4 +6,4 @@ lwip-1.3.0.tar.gz
|
|||
pciutils-2.2.9.tar.bz2
|
||||
zlib-1.2.3.tar.gz
|
||||
polarssl-1.1.4-gpl.tgz
|
||||
/xen-4.14.1.tar.gz
|
||||
/xen-4.14.3.tar.gz
|
||||
|
|
|
|||
2
sources
2
sources
|
|
@ -4,4 +4,4 @@ SHA512 (newlib-1.16.0.tar.gz) = 40eb96bbc6736a16b6399e0cdb73e853d0d90b685c967e77
|
|||
SHA512 (zlib-1.2.3.tar.gz) = 021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea34a70504ce9622b1c2626fce40675bc8282cf5f5ade18473656abc38050f72f5d6480507a2106e
|
||||
SHA512 (polarssl-1.1.4-gpl.tgz) = 88da614e4d3f4409c4fd3bb3e44c7587ba051e3fed4e33d526069a67e8180212e1ea22da984656f50e290049f60ddca65383e5983c0f8884f648d71f698303ad
|
||||
SHA512 (pciutils-2.2.9.tar.bz2) = 2b3d98d027e46d8c08037366dde6f0781ca03c610ef2b380984639e4ef39899ed8d8b8e4cd9c9dc54df101279b95879bd66bfd4d04ad07fef41e847ea7ae32b5
|
||||
SHA512 (xen-4.14.1.tar.gz) = c75cbec82793435f5a7026626ffdb2e9a2166b42d2be4b2f1194240e0312458124f0ebd53eeb02ce7330c22afe402a28a96b32f8af66e41e9416fe94535724c9
|
||||
SHA512 (xen-4.14.3.tar.gz) = b462fcc1549f6e57f7f2a4fd10ce1e957a25a6a7c0319672b62699468f6c4330b9cd0cf2b0231b5cce94f4bb142a957eb8aa58aa0ffb5c85b37211d6b34ccf16
|
||||
|
|
|
|||
|
|
@ -1,15 +1,3 @@
|
|||
--- xen-4.14.0/xen/include/crypto/rijndael.h.orig 2020-07-23 16:07:51.000000000 +0100
|
||||
+++ xen-4.14.0/xen/include/crypto/rijndael.h 2020-10-24 14:59:34.349318594 +0100
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int);
|
||||
int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int);
|
||||
-void rijndaelEncrypt(const unsigned int [], int, const unsigned char [],
|
||||
- unsigned char []);
|
||||
+void rijndaelEncrypt(const unsigned int [], int, const unsigned char [16],
|
||||
+ unsigned char [16]);
|
||||
|
||||
#endif /* __RIJNDAEL_H */
|
||||
--- xen-4.14.0/xen/include/crypto/vmac.h.orig 2020-07-23 16:07:51.000000000 +0100
|
||||
+++ xen-4.14.0/xen/include/crypto/vmac.h 2020-10-24 15:45:49.246467465 +0100
|
||||
@@ -142,7 +142,7 @@
|
||||
|
|
@ -21,28 +9,6 @@
|
|||
unsigned int mbytes,
|
||||
vmac_ctx_t *ctx);
|
||||
|
||||
--- xen-4.14.0/tools/libs/foreignmemory/linux.c.orig 2020-07-23 16:07:51.000000000 +0100
|
||||
+++ xen-4.14.0/tools/libs/foreignmemory/linux.c 2020-10-25 21:36:00.982040566 +0000
|
||||
@@ -162,7 +162,7 @@
|
||||
void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem,
|
||||
uint32_t dom, void *addr,
|
||||
int prot, int flags, size_t num,
|
||||
- const xen_pfn_t arr[/*num*/], int err[/*num*/])
|
||||
+ const xen_pfn_t arr[num], int err[num])
|
||||
{
|
||||
int fd = fmem->fd;
|
||||
privcmd_mmapbatch_v2_t ioctlx;
|
||||
--- xen-4.14.0/tools/libs/foreignmemory/minios.c.orig 2020-07-23 16:07:51.000000000 +0100
|
||||
+++ xen-4.14.0/tools/libs/foreignmemory/minios.c 2020-10-26 22:36:12.423883688 +0000
|
||||
@@ -42,7 +42,7 @@
|
||||
void *osdep_xenforeignmemory_map(xenforeignmemory_handle *fmem,
|
||||
uint32_t dom, void *addr,
|
||||
int prot, int flags, size_t num,
|
||||
- const xen_pfn_t arr[/*num*/], int err[/*num*/])
|
||||
+ const xen_pfn_t arr[num], int err[num])
|
||||
{
|
||||
unsigned long pt_prot = 0;
|
||||
if (prot & PROT_READ)
|
||||
diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c
|
||||
index 320e06f..618ae92 100644
|
||||
--- a/xen/arch/x86/tboot.c
|
||||
|
|
@ -56,20 +22,3 @@ index 320e06f..618ae92 100644
|
|||
|
||||
/* Look for valid page-aligned address for shared page. */
|
||||
if ( !opt_tboot_pa || (opt_tboot_pa & ~PAGE_MASK) )
|
||||
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
index 84bb8e0..6ecf5db 100644
|
||||
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
|
||||
@@ -725,9 +725,9 @@ union vex {
|
||||
#define copy_VEX(ptr, vex) ({ \
|
||||
if ( !mode_64bit() ) \
|
||||
(vex).reg |= 8; \
|
||||
- (ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
|
||||
- (ptr)[1 - PFX_BYTES] = (vex).raw[0]; \
|
||||
- (ptr)[2 - PFX_BYTES] = (vex).raw[1]; \
|
||||
+ ((volatile uint8_t *)ptr)[0 - PFX_BYTES] = ext < ext_8f08 ? 0xc4 : 0x8f; \
|
||||
+ ((volatile uint8_t *)ptr)[1 - PFX_BYTES] = (vex).raw[0]; \
|
||||
+ ((volatile uint8_t *)ptr)[2 - PFX_BYTES] = (vex).raw[1]; \
|
||||
container_of((ptr) + 1 - PFX_BYTES, typeof(vex), raw[0]); \
|
||||
})
|
||||
|
||||
|
|
|
|||
95
xen.spec
95
xen.spec
|
|
@ -57,8 +57,8 @@
|
|||
|
||||
Summary: Xen is a virtual machine monitor
|
||||
Name: xen
|
||||
Version: 4.14.1
|
||||
Release: 5%{?dist}
|
||||
Version: 4.14.3
|
||||
Release: 3%{?dist}
|
||||
License: GPLv2+ and LGPLv2+ and BSD
|
||||
URL: http://xen.org/
|
||||
Source0: https://downloads.xenproject.org/release/xen/%{version}/xen-%{version}.tar.gz
|
||||
|
|
@ -112,14 +112,17 @@ Patch40: xen.drop.brctl.patch
|
|||
Patch41: xen.gcc9.fixes.patch
|
||||
Patch42: xen.gcc10.fixes.patch
|
||||
Patch43: xen.gcc11.fixes.patch
|
||||
Patch44: xsa360-4.14.patch
|
||||
Patch45: xen.git-7c9f81687ad611515474b1c17afc2f79f19faef5.patch
|
||||
Patch46: xen.git-35d2960ae65f28106fdc5c2130f5f08fadca0e4c.patch
|
||||
Patch47: xen.git-d6627cf1b63ce57a6a7e2c1800dbc50eed742c32.patch
|
||||
Patch48: xen.git-d8099d94dfaa3573bd86ebfc457cbc8f70a3ecda.patch
|
||||
Patch49: xen.git-8169f82049efb5b2044b33aa482ba3a136b7804d.patch
|
||||
Patch50: xsa363.patch
|
||||
Patch51: xsa364.patch
|
||||
Patch51: xsa386.patch
|
||||
Patch52: xsa385-4.15.patch
|
||||
Patch53: xsa388-4.14-1.patch
|
||||
Patch54: xsa388-4.14-2.patch
|
||||
Patch55: xsa389-4.14.patch
|
||||
|
||||
|
||||
%if %build_qemutrad
|
||||
|
|
@ -328,7 +331,6 @@ manage Xen virtual machines.
|
|||
%patch41 -p1
|
||||
%patch42 -p1
|
||||
%patch43 -p1
|
||||
%patch44 -p1
|
||||
%patch45 -p1
|
||||
%patch46 -p1
|
||||
%patch47 -p1
|
||||
|
|
@ -336,6 +338,10 @@ manage Xen virtual machines.
|
|||
%patch49 -p1
|
||||
%patch50 -p1
|
||||
%patch51 -p1
|
||||
%patch52 -p1
|
||||
%patch53 -p1
|
||||
%patch54 -p1
|
||||
%patch55 -p1
|
||||
|
||||
# qemu-xen-traditional patches
|
||||
pushd tools/qemu-xen-traditional
|
||||
|
|
@ -612,16 +618,21 @@ do_it() {
|
|||
if [ ! -d $TARGET ]; then
|
||||
mkdir $TARGET
|
||||
fi
|
||||
if [ -f $DIR/relocator.mod -a ! -f $TARGET/relocator.mod ]; then
|
||||
cp -p $DIR/relocator.mod $TARGET/relocator.mod
|
||||
fi
|
||||
if [ -f $DIR/multiboot2.mod -a ! -f $TARGET/multiboot2.mod ]; then
|
||||
cp -p $DIR/multiboot2.mod $TARGET/multiboot2.mod
|
||||
fi
|
||||
for m in relocator.mod multiboot2.mod; do
|
||||
if [ -f $DIR/$m ]; then
|
||||
if [ ! -f $TARGET/$m ] || ! cmp -s $DIR/$m $TARGET/$m; then
|
||||
cp -p $DIR/$m $TARGET/$m
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
if [ $1 == 1 -a -f /sbin/grub2-mkconfig ]; then
|
||||
%if "%dist" <= ".fc33"
|
||||
for f in /boot/grub2/grub.cfg /boot/efi/EFI/fedora/grub.cfg; do
|
||||
%else
|
||||
for f in /boot/grub2/grub.cfg; do
|
||||
%endif
|
||||
if [ -f $f ]; then
|
||||
/sbin/grub2-mkconfig -o $f
|
||||
sed -i -e '/insmod module2/d' $f
|
||||
|
|
@ -633,17 +644,26 @@ if [ -f /sbin/grub2-mkconfig ]; then
|
|||
DIR=/usr/lib/grub/i386-pc
|
||||
TARGET=/boot/grub2/i386-pc
|
||||
do_it $DIR $TARGET
|
||||
DIR=/usr/lib/grub/x86_64-efi
|
||||
TARGET=/boot/grub2/x86_64-efi
|
||||
do_it $DIR $TARGET
|
||||
fi
|
||||
%if "%dist" <= ".fc33"
|
||||
if [ -f /boot/efi/EFI/fedora/grub.cfg ]; then
|
||||
DIR=/usr/lib/grub/x86_64-efi
|
||||
TARGET=/boot/efi/EFI/fedora/x86_64-efi
|
||||
do_it $DIR $TARGET
|
||||
fi
|
||||
%endif
|
||||
fi
|
||||
|
||||
%postun hypervisor
|
||||
if [ -f /sbin/grub2-mkconfig ]; then
|
||||
%if "%dist" <= ".fc33"
|
||||
for f in /boot/grub2/grub.cfg /boot/efi/EFI/fedora/grub.cfg; do
|
||||
%else
|
||||
for f in /boot/grub2/grub.cfg; do
|
||||
%endif
|
||||
if [ -f $f ]; then
|
||||
/sbin/grub2-mkconfig -o $f
|
||||
sed -i -e '/insmod module2/d' $f
|
||||
|
|
@ -928,6 +948,59 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Nov 23 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.3-3
|
||||
- guests may exceed their designated memory limit [XSA-385, CVE-2021-28706]
|
||||
- PoD operations on misaligned GFNs [XSA-388, CVE-2021-28704, CVE-2021-28707
|
||||
CVE-2021-28708]
|
||||
- issues with partially successful P2M updates on x86 [XSA-389,
|
||||
CVE-2021-28705, CVE-2021-28709]
|
||||
|
||||
* Wed Oct 06 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.3-2
|
||||
- PCI devices with RMRRs not deassigned correctly [XSA-386, CVE-2021-28702]
|
||||
(#2011248)
|
||||
|
||||
* Mon Sep 13 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.3-1
|
||||
- update to xen-4.14.3
|
||||
remove or adjust patches now included or superceded upstream
|
||||
|
||||
* Wed Sep 08 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.2-4
|
||||
- Another race in XENMAPSPACE_grant_table handling [XSA-384, CVE-2021-28701]
|
||||
(#2002786)
|
||||
- bugfix for XSA-380
|
||||
- stop editing grub files in /boot/efi/EFI/fedora on Fedora 34
|
||||
|
||||
* Sat Aug 28 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.2-3
|
||||
- IOMMU page mapping issues on x86 [XSA-378, CVE-2021-28694,
|
||||
CVE-2021-28695, CVE-2021-28696] (#1997531) (#1997568)
|
||||
(#1997537)
|
||||
- grant table v2 status pages may remain accessible after de-allocation
|
||||
[XSA-379, CVE-2021-28697] (#1997520)
|
||||
- long running loops in grant table handling [XSA-380, CVE-2021-28698]
|
||||
(#1997526)
|
||||
- inadequate grant-v2 status frames array bounds check [XSA-382,
|
||||
CVE-2021-28699] (#1997523)
|
||||
- xen/arm: No memory limit for dom0less domUs [XSA-383, CVE-2021-28700]
|
||||
(#1997527)
|
||||
- grub x86_64-efi modules now go into /boot/grub2
|
||||
|
||||
* Tue Jun 08 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.2-2
|
||||
- xen/arm: Boot modules are not scrubbed [XSA-372, CVE-2021-28693]
|
||||
(#1970542)
|
||||
- inappropriate x86 IOMMU timeout detection / handling
|
||||
[XSA-373, CVE-2021-28692] (#1970540)
|
||||
- Speculative Code Store Bypass [XSA-375, CVE-2021-0089, CVE-2021-26313]
|
||||
(#1970531)
|
||||
- x86: TSX Async Abort protections not restored after S3
|
||||
[XSA-377, CVE-2021-28690] (#1970546)
|
||||
|
||||
* Tue May 04 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.2-1
|
||||
- update to 4.14.2
|
||||
remove or adjust patch content now included or superceded upstream
|
||||
- re-copy grub modules if they have changed
|
||||
|
||||
* Thu Mar 18 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.1-7
|
||||
- HVM soft-reset crashes toolstack [XSA-368, CVE-2021-28687] (#1940610)
|
||||
|
||||
* Tue Feb 16 2021 Michael Young <m.a.young@durham.ac.uk> - 4.14.1-5
|
||||
- Linux: display frontend "be-alloc" mode is unsupported (comment only)
|
||||
[XSA-363, CVE-2021-26934] (#1929549)
|
||||
|
|
|
|||
|
|
@ -1,97 +0,0 @@
|
|||
From: Roger Pau Monne <roger.pau@citrix.com>
|
||||
Subject: x86/dpci: do not remove pirqs from domain tree on unbind
|
||||
|
||||
A fix for a previous issue removed the pirqs from the domain tree when
|
||||
they are unbound in order to prevent shared pirqs from triggering a
|
||||
BUG_ON in __pirq_guest_unbind if they are unbound multiple times. That
|
||||
caused free_domain_pirqs to no longer unmap the pirqs because they
|
||||
are gone from the domain pirq tree, thus leaving stale unbound pirqs
|
||||
after domain destruction if the domain had mapped dpci pirqs after
|
||||
shutdown.
|
||||
|
||||
Take a different approach to fix the original issue, instead of
|
||||
removing the pirq from d->pirq_tree clear the flags of the dpci pirq
|
||||
struct to signal that the pirq is now unbound. This prevents calling
|
||||
pirq_guest_unbind multiple times for the same pirq without having to
|
||||
remove it from the domain pirq tree.
|
||||
|
||||
This is XSA-360.
|
||||
|
||||
Fixes: 5b58dad089 ('x86/pass-through: avoid double IRQ unbind during domain cleanup')
|
||||
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/arch/x86/irq.c
|
||||
+++ b/xen/arch/x86/irq.c
|
||||
@@ -1331,7 +1331,7 @@ void (pirq_cleanup_check)(struct pirq *p
|
||||
}
|
||||
|
||||
if ( radix_tree_delete(&d->pirq_tree, pirq->pirq) != pirq )
|
||||
- BUG_ON(!d->is_dying);
|
||||
+ BUG();
|
||||
}
|
||||
|
||||
/* Flush all ready EOIs from the top of this CPU's pending-EOI stack. */
|
||||
--- a/xen/drivers/passthrough/pci.c
|
||||
+++ b/xen/drivers/passthrough/pci.c
|
||||
@@ -862,6 +862,10 @@ static int pci_clean_dpci_irq(struct dom
|
||||
{
|
||||
struct dev_intx_gsi_link *digl, *tmp;
|
||||
|
||||
+ if ( !pirq_dpci->flags )
|
||||
+ /* Already processed. */
|
||||
+ return 0;
|
||||
+
|
||||
pirq_guest_unbind(d, dpci_pirq(pirq_dpci));
|
||||
|
||||
if ( pt_irq_need_timer(pirq_dpci->flags) )
|
||||
@@ -872,15 +876,10 @@ static int pci_clean_dpci_irq(struct dom
|
||||
list_del(&digl->list);
|
||||
xfree(digl);
|
||||
}
|
||||
+ /* Note the pirq is now unbound. */
|
||||
+ pirq_dpci->flags = 0;
|
||||
|
||||
- radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq);
|
||||
-
|
||||
- if ( !pt_pirq_softirq_active(pirq_dpci) )
|
||||
- return 0;
|
||||
-
|
||||
- domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci;
|
||||
-
|
||||
- return -ERESTART;
|
||||
+ return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0;
|
||||
}
|
||||
|
||||
static int pci_clean_dpci_irqs(struct domain *d)
|
||||
@@ -897,18 +896,8 @@ static int pci_clean_dpci_irqs(struct do
|
||||
hvm_irq_dpci = domain_get_irq_dpci(d);
|
||||
if ( hvm_irq_dpci != NULL )
|
||||
{
|
||||
- int ret = 0;
|
||||
-
|
||||
- if ( hvm_irq_dpci->pending_pirq_dpci )
|
||||
- {
|
||||
- if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) )
|
||||
- ret = -ERESTART;
|
||||
- else
|
||||
- hvm_irq_dpci->pending_pirq_dpci = NULL;
|
||||
- }
|
||||
+ int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
|
||||
|
||||
- if ( !ret )
|
||||
- ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
|
||||
if ( ret )
|
||||
{
|
||||
spin_unlock(&d->event_lock);
|
||||
--- a/xen/include/asm-x86/hvm/irq.h
|
||||
+++ b/xen/include/asm-x86/hvm/irq.h
|
||||
@@ -160,8 +160,6 @@ struct hvm_irq_dpci {
|
||||
DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
|
||||
/* Record of mapped Links */
|
||||
uint8_t link_cnt[NR_LINK];
|
||||
- /* Clean up: Entry with a softirq invocation pending / in progress. */
|
||||
- struct hvm_pirq_dpci *pending_pirq_dpci;
|
||||
};
|
||||
|
||||
/* Machine IRQ to guest device/intx mapping. */
|
||||
69
xsa364.patch
69
xsa364.patch
|
|
@ -1,69 +0,0 @@
|
|||
From dadb5b4b21c904ce59024c686eb1c55be8f46c52 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Grall <jgrall@amazon.com>
|
||||
Date: Thu, 21 Jan 2021 10:16:08 +0000
|
||||
Subject: [PATCH] xen/page_alloc: Only flush the page to RAM once we know they
|
||||
are scrubbed
|
||||
|
||||
At the moment, each page are flushed to RAM just after the allocator
|
||||
found some free pages. However, this is happening before check if the
|
||||
page was scrubbed.
|
||||
|
||||
As a consequence, on Arm, a guest may be able to access the old content
|
||||
of the scrubbed pages if it has cache disabled (default at boot) and
|
||||
the content didn't reach the Point of Coherency.
|
||||
|
||||
The flush is now moved after we know the content of the page will not
|
||||
change. This also has the benefit to reduce the amount of work happening
|
||||
with the heap_lock held.
|
||||
|
||||
This is XSA-364.
|
||||
|
||||
Fixes: 307c3be3ccb2 ("mm: Don't scrub pages while holding heap lock in alloc_heap_pages()")
|
||||
Signed-off-by: Julien Grall <jgrall@amazon.com>
|
||||
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
||||
---
|
||||
xen/common/page_alloc.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
|
||||
index 02ac1fa613e7..1744e6faa5c4 100644
|
||||
--- a/xen/common/page_alloc.c
|
||||
+++ b/xen/common/page_alloc.c
|
||||
@@ -924,6 +924,7 @@ static struct page_info *alloc_heap_pages(
|
||||
bool need_tlbflush = false;
|
||||
uint32_t tlbflush_timestamp = 0;
|
||||
unsigned int dirty_cnt = 0;
|
||||
+ mfn_t mfn;
|
||||
|
||||
/* Make sure there are enough bits in memflags for nodeID. */
|
||||
BUILD_BUG_ON((_MEMF_bits - _MEMF_node) < (8 * sizeof(nodeid_t)));
|
||||
@@ -1022,11 +1023,6 @@ static struct page_info *alloc_heap_pages(
|
||||
pg[i].u.inuse.type_info = 0;
|
||||
page_set_owner(&pg[i], NULL);
|
||||
|
||||
- /* Ensure cache and RAM are consistent for platforms where the
|
||||
- * guest can control its own visibility of/through the cache.
|
||||
- */
|
||||
- flush_page_to_ram(mfn_x(page_to_mfn(&pg[i])),
|
||||
- !(memflags & MEMF_no_icache_flush));
|
||||
}
|
||||
|
||||
spin_unlock(&heap_lock);
|
||||
@@ -1062,6 +1058,14 @@ static struct page_info *alloc_heap_pages(
|
||||
if ( need_tlbflush )
|
||||
filtered_flush_tlb_mask(tlbflush_timestamp);
|
||||
|
||||
+ /*
|
||||
+ * Ensure cache and RAM are consistent for platforms where the guest
|
||||
+ * can control its own visibility of/through the cache.
|
||||
+ */
|
||||
+ mfn = page_to_mfn(pg);
|
||||
+ for ( i = 0; i < (1U << order); i++ )
|
||||
+ flush_page_to_ram(mfn_x(mfn) + i, !(memflags & MEMF_no_icache_flush));
|
||||
+
|
||||
return pg;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
96
xsa385-4.15.patch
Normal file
96
xsa385-4.15.patch
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
From: Julien Grall <jgrall@amazon.com>
|
||||
Subject: xen/page_alloc: Harden assign_pages()
|
||||
|
||||
domain_tot_pages() and d->max_pages are 32-bit values. While the order
|
||||
should always be quite small, it would still be possible to overflow
|
||||
if domain_tot_pages() is near to (2^32 - 1).
|
||||
|
||||
As this code may be called by a guest via XENMEM_increase_reservation
|
||||
and XENMEM_populate_physmap, we want to make sure the guest is not going
|
||||
to be able to allocate more than it is allowed.
|
||||
|
||||
Rework the allocation check to avoid any possible overflow. While the
|
||||
check domain_tot_pages() < d->max_pages should technically not be
|
||||
necessary, it is probably best to have it to catch any possible
|
||||
inconsistencies in the future.
|
||||
|
||||
This is CVE-2021-28706 / XSA-385.
|
||||
|
||||
Signed-off-by: Julien Grall <jgrall@amazon.com>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
--- a/xen/common/grant_table.c
|
||||
+++ b/xen/common/grant_table.c
|
||||
@@ -2336,7 +2336,8 @@ gnttab_transfer(
|
||||
* pages when it is dying.
|
||||
*/
|
||||
if ( unlikely(e->is_dying) ||
|
||||
- unlikely(domain_tot_pages(e) >= e->max_pages) )
|
||||
+ unlikely(domain_tot_pages(e) >= e->max_pages) ||
|
||||
+ unlikely(!(e->tot_pages + 1)) )
|
||||
{
|
||||
spin_unlock(&e->page_alloc_lock);
|
||||
|
||||
@@ -2345,8 +2346,8 @@ gnttab_transfer(
|
||||
e->domain_id);
|
||||
else
|
||||
gdprintk(XENLOG_INFO,
|
||||
- "Transferee d%d has no headroom (tot %u, max %u)\n",
|
||||
- e->domain_id, domain_tot_pages(e), e->max_pages);
|
||||
+ "Transferee %pd has no headroom (tot %u, max %u, ex %u)\n",
|
||||
+ e, domain_tot_pages(e), e->max_pages, e->extra_pages);
|
||||
|
||||
gop.status = GNTST_general_error;
|
||||
goto unlock_and_copyback;
|
||||
--- a/xen/common/page_alloc.c
|
||||
+++ b/xen/common/page_alloc.c
|
||||
@@ -2298,20 +2298,43 @@ int assign_pages(
|
||||
}
|
||||
else if ( !(memflags & MEMF_no_refcount) )
|
||||
{
|
||||
- unsigned int tot_pages = domain_tot_pages(d) + (1 << order);
|
||||
+ unsigned int tot_pages = domain_tot_pages(d), nr = 1u << order;
|
||||
|
||||
if ( unlikely(tot_pages > d->max_pages) )
|
||||
{
|
||||
- gprintk(XENLOG_INFO, "Over-allocation for domain %u: "
|
||||
- "%u > %u\n", d->domain_id, tot_pages, d->max_pages);
|
||||
+ gprintk(XENLOG_INFO, "Inconsistent allocation for %pd: %u > %u\n",
|
||||
+ d, tot_pages, d->max_pages);
|
||||
+ rc = -EPERM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(nr > d->max_pages - tot_pages) )
|
||||
+ {
|
||||
+ gprintk(XENLOG_INFO, "Over-allocation for %pd: %Lu > %u\n",
|
||||
+ d, tot_pages + 0ull + nr, d->max_pages);
|
||||
rc = -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
- if ( !(memflags & MEMF_no_refcount) &&
|
||||
- unlikely(domain_adjust_tot_pages(d, 1 << order) == (1 << order)) )
|
||||
- get_knownalive_domain(d);
|
||||
+ if ( !(memflags & MEMF_no_refcount) )
|
||||
+ {
|
||||
+ unsigned int nr = 1u << order;
|
||||
+
|
||||
+ if ( unlikely(d->tot_pages + nr < nr) )
|
||||
+ {
|
||||
+ gprintk(XENLOG_INFO,
|
||||
+ "Excess allocation for %pd: %Lu (%u extra)\n",
|
||||
+ d, d->tot_pages + 0ull + nr, d->extra_pages);
|
||||
+ if ( pg[0].count_info & PGC_extra )
|
||||
+ d->extra_pages -= nr;
|
||||
+ rc = -E2BIG;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(domain_adjust_tot_pages(d, nr) == nr) )
|
||||
+ get_knownalive_domain(d);
|
||||
+ }
|
||||
|
||||
for ( i = 0; i < (1 << order); i++ )
|
||||
{
|
||||
29
xsa386.patch
Normal file
29
xsa386.patch
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: VT-d: fix deassign of device with RMRR
|
||||
Date: Fri, 1 Oct 2021 15:05:42 +0200
|
||||
|
||||
Ignoring a specific error code here was not meant to short circuit
|
||||
deassign to _just_ the unmapping of RMRRs. This bug was previously
|
||||
hidden by the bogus (potentially indefinite) looping in
|
||||
pci_release_devices(), until f591755823a7 ("IOMMU/PCI: don't let domain
|
||||
cleanup continue when device de-assignment failed") fixed that loop.
|
||||
|
||||
This is CVE-2021-28702 / XSA-386.
|
||||
|
||||
Fixes: 8b99f4400b69 ("VT-d: fix RMRR related error handling")
|
||||
Reported-by: Ivan Kardykov <kardykov@tabit.pro>
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Tested-by: Ivan Kardykov <kardykov@tabit.pro>
|
||||
|
||||
--- a/xen/drivers/passthrough/vtd/iommu.c
|
||||
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
||||
@@ -2409,7 +2409,7 @@ static int reassign_device_ownership(
|
||||
ret = iommu_identity_mapping(source, p2m_access_x,
|
||||
rmrr->base_address,
|
||||
rmrr->end_address, 0);
|
||||
- if ( ret != -ENOENT )
|
||||
+ if ( ret && ret != -ENOENT )
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
174
xsa388-4.14-1.patch
Normal file
174
xsa388-4.14-1.patch
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/PoD: deal with misaligned GFNs
|
||||
|
||||
Users of XENMEM_decrease_reservation and XENMEM_populate_physmap aren't
|
||||
required to pass in order-aligned GFN values. (While I consider this
|
||||
bogus, I don't think we can fix this there, as that might break existing
|
||||
code, e.g Linux'es swiotlb, which - while affecting PV only - until
|
||||
recently had been enforcing only page alignment on the original
|
||||
allocation.) Only non-PoD code paths (guest_physmap_{add,remove}_page(),
|
||||
p2m_set_entry()) look to be dealing with this properly (in part by being
|
||||
implemented inefficiently, handling every 4k page separately).
|
||||
|
||||
Introduce wrappers taking care of splitting the incoming request into
|
||||
aligned chunks, without putting much effort in trying to determine the
|
||||
largest possible chunk at every iteration.
|
||||
|
||||
Also "handle" p2m_set_entry() failure for non-order-0 requests by
|
||||
crashing the domain in one more place. Alongside putting a log message
|
||||
there, also add one to the other similar path.
|
||||
|
||||
Note regarding locking: This is left in the actual worker functions on
|
||||
the assumption that callers aren't guaranteed atomicity wrt acting on
|
||||
multiple pages at a time. For mis-aligned GFNs gfn_lock() wouldn't have
|
||||
locked the correct GFN range anyway, if it didn't simply resolve to
|
||||
p2m_lock(), and for well-behaved callers there continues to be only a
|
||||
single iteration, i.e. behavior is unchanged for them. (FTAOD pulling
|
||||
out just pod_lock() into p2m_pod_decrease_reservation() would result in
|
||||
a lock order violation.)
|
||||
|
||||
This is CVE-2021-28704 and CVE-2021-28707 / part of XSA-388.
|
||||
|
||||
Fixes: 3c352011c0d3 ("x86/PoD: shorten certain operations on higher order ranges")
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m-pod.c
|
||||
+++ b/xen/arch/x86/mm/p2m-pod.c
|
||||
@@ -495,7 +495,7 @@ p2m_pod_zero_check_superpage(struct p2m_
|
||||
|
||||
|
||||
/*
|
||||
- * This function is needed for two reasons:
|
||||
+ * This pair of functions is needed for two reasons:
|
||||
* + To properly handle clearing of PoD entries
|
||||
* + To "steal back" memory being freed for the PoD cache, rather than
|
||||
* releasing it.
|
||||
@@ -503,8 +503,8 @@ p2m_pod_zero_check_superpage(struct p2m_
|
||||
* Once both of these functions have been completed, we can return and
|
||||
* allow decrease_reservation() to handle everything else.
|
||||
*/
|
||||
-unsigned long
|
||||
-p2m_pod_decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
|
||||
+static unsigned long
|
||||
+decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
|
||||
{
|
||||
unsigned long ret = 0, i, n;
|
||||
struct p2m_domain *p2m = p2m_get_hostp2m(d);
|
||||
@@ -551,8 +551,10 @@ p2m_pod_decrease_reservation(struct doma
|
||||
* All PoD: Mark the whole region invalid and tell caller
|
||||
* we're done.
|
||||
*/
|
||||
- if ( p2m_set_entry(p2m, gfn, INVALID_MFN, order, p2m_invalid,
|
||||
- p2m->default_access) )
|
||||
+ int rc = p2m_set_entry(p2m, gfn, INVALID_MFN, order, p2m_invalid,
|
||||
+ p2m->default_access);
|
||||
+
|
||||
+ if ( rc )
|
||||
{
|
||||
/*
|
||||
* If this fails, we can't tell how much of the range was changed.
|
||||
@@ -560,7 +562,12 @@ p2m_pod_decrease_reservation(struct doma
|
||||
* impossible.
|
||||
*/
|
||||
if ( order != 0 )
|
||||
+ {
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "%pd: marking GFN %#lx (order %u) as non-PoD failed: %d\n",
|
||||
+ d, gfn_x(gfn), order, rc);
|
||||
domain_crash(d);
|
||||
+ }
|
||||
goto out_unlock;
|
||||
}
|
||||
ret = 1UL << order;
|
||||
@@ -667,6 +674,22 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+unsigned long
|
||||
+p2m_pod_decrease_reservation(struct domain *d, gfn_t gfn, unsigned int order)
|
||||
+{
|
||||
+ unsigned long left = 1UL << order, ret = 0;
|
||||
+ unsigned int chunk_order = find_first_set_bit(gfn_x(gfn) | left);
|
||||
+
|
||||
+ do {
|
||||
+ ret += decrease_reservation(d, gfn, chunk_order);
|
||||
+
|
||||
+ left -= 1UL << chunk_order;
|
||||
+ gfn = gfn_add(gfn, 1UL << chunk_order);
|
||||
+ } while ( left );
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void p2m_pod_dump_data(struct domain *d)
|
||||
{
|
||||
struct p2m_domain *p2m = p2m_get_hostp2m(d);
|
||||
@@ -1266,19 +1289,15 @@ remap_and_retry:
|
||||
return true;
|
||||
}
|
||||
|
||||
-
|
||||
-int
|
||||
-guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn_l,
|
||||
- unsigned int order)
|
||||
+static int
|
||||
+mark_populate_on_demand(struct domain *d, unsigned long gfn_l,
|
||||
+ unsigned int order)
|
||||
{
|
||||
struct p2m_domain *p2m = p2m_get_hostp2m(d);
|
||||
gfn_t gfn = _gfn(gfn_l);
|
||||
unsigned long i, n, pod_count = 0;
|
||||
int rc = 0;
|
||||
|
||||
- if ( !paging_mode_translate(d) )
|
||||
- return -EINVAL;
|
||||
-
|
||||
gfn_lock(p2m, gfn, order);
|
||||
|
||||
P2M_DEBUG("mark pod gfn=%#lx\n", gfn_l);
|
||||
@@ -1316,12 +1335,44 @@ guest_physmap_mark_populate_on_demand(st
|
||||
BUG_ON(p2m->pod.entry_count < 0);
|
||||
pod_unlock(p2m);
|
||||
}
|
||||
+ else if ( order )
|
||||
+ {
|
||||
+ /*
|
||||
+ * If this failed, we can't tell how much of the range was changed.
|
||||
+ * Best to crash the domain.
|
||||
+ */
|
||||
+ printk(XENLOG_G_ERR
|
||||
+ "%pd: marking GFN %#lx (order %u) as PoD failed: %d\n",
|
||||
+ d, gfn_l, order, rc);
|
||||
+ domain_crash(d);
|
||||
+ }
|
||||
|
||||
out:
|
||||
gfn_unlock(p2m, gfn, order);
|
||||
|
||||
return rc;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
|
||||
+ unsigned int order)
|
||||
+{
|
||||
+ unsigned long left = 1UL << order;
|
||||
+ unsigned int chunk_order = find_first_set_bit(gfn | left);
|
||||
+ int rc;
|
||||
+
|
||||
+ if ( !paging_mode_translate(d) )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ do {
|
||||
+ rc = mark_populate_on_demand(d, gfn, chunk_order);
|
||||
+
|
||||
+ left -= 1UL << chunk_order;
|
||||
+ gfn += 1UL << chunk_order;
|
||||
+ } while ( !rc && left );
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
|
||||
void p2m_pod_init(struct p2m_domain *p2m)
|
||||
{
|
||||
36
xsa388-4.14-2.patch
Normal file
36
xsa388-4.14-2.patch
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/PoD: handle intermediate page orders in p2m_pod_cache_add()
|
||||
|
||||
p2m_pod_decrease_reservation() may pass pages to the function which
|
||||
aren't 4k, 2M, or 1G. Handle all intermediate orders as well, to avoid
|
||||
hitting the BUG() at the switch() statement's "default" case.
|
||||
|
||||
This is CVE-2021-28708 / part of XSA-388.
|
||||
|
||||
Fixes: 3c352011c0d3 ("x86/PoD: shorten certain operations on higher order ranges")
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m-pod.c
|
||||
+++ b/xen/arch/x86/mm/p2m-pod.c
|
||||
@@ -111,15 +111,13 @@ p2m_pod_cache_add(struct p2m_domain *p2m
|
||||
/* Then add to the appropriate populate-on-demand list. */
|
||||
switch ( order )
|
||||
{
|
||||
- case PAGE_ORDER_1G:
|
||||
- for ( i = 0; i < (1UL << PAGE_ORDER_1G); i += 1UL << PAGE_ORDER_2M )
|
||||
+ case PAGE_ORDER_2M ... PAGE_ORDER_1G:
|
||||
+ for ( i = 0; i < (1UL << order); i += 1UL << PAGE_ORDER_2M )
|
||||
page_list_add_tail(page + i, &p2m->pod.super);
|
||||
break;
|
||||
- case PAGE_ORDER_2M:
|
||||
- page_list_add_tail(page, &p2m->pod.super);
|
||||
- break;
|
||||
- case PAGE_ORDER_4K:
|
||||
- page_list_add_tail(page, &p2m->pod.single);
|
||||
+ case PAGE_ORDER_4K ... PAGE_ORDER_2M - 1:
|
||||
+ for ( i = 0; i < (1UL << order); i += 1UL << PAGE_ORDER_4K )
|
||||
+ page_list_add_tail(page + i, &p2m->pod.single);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
180
xsa389-4.14.patch
Normal file
180
xsa389-4.14.patch
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
From: Jan Beulich <jbeulich@suse.com>
|
||||
Subject: x86/P2M: deal with partial success of p2m_set_entry()
|
||||
|
||||
M2P and PoD stats need to remain in sync with P2M; if an update succeeds
|
||||
only partially, respective adjustments need to be made. If updates get
|
||||
made before the call, they may also need undoing upon complete failure
|
||||
(i.e. including the single-page case).
|
||||
|
||||
Log-dirty state would better also be kept in sync.
|
||||
|
||||
Note that the change to set_typed_p2m_entry() may not be strictly
|
||||
necessary (due to the order restriction enforced near the top of the
|
||||
function), but is being kept here to be on the safe side.
|
||||
|
||||
This is CVE-2021-28705 and CVE-2021-28709 / XSA-389.
|
||||
|
||||
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||
|
||||
--- a/xen/arch/x86/mm/p2m.c
|
||||
+++ b/xen/arch/x86/mm/p2m.c
|
||||
@@ -780,6 +780,7 @@ p2m_remove_page(struct p2m_domain *p2m,
|
||||
unsigned long i;
|
||||
p2m_type_t t;
|
||||
p2m_access_t a;
|
||||
+ int rc;
|
||||
|
||||
/* IOMMU for PV guests is handled in get_page_type() and put_page(). */
|
||||
if ( !paging_mode_translate(p2m->domain) )
|
||||
@@ -813,8 +814,27 @@ p2m_remove_page(struct p2m_domain *p2m,
|
||||
}
|
||||
}
|
||||
|
||||
- return p2m_set_entry(p2m, gfn, INVALID_MFN, page_order, p2m_invalid,
|
||||
- p2m->default_access);
|
||||
+ rc = p2m_set_entry(p2m, gfn, INVALID_MFN, page_order, p2m_invalid,
|
||||
+ p2m->default_access);
|
||||
+ if ( likely(!rc) || !mfn_valid(mfn) )
|
||||
+ return rc;
|
||||
+
|
||||
+ /*
|
||||
+ * The operation may have partially succeeded. For the failed part we need
|
||||
+ * to undo the M2P update and, out of precaution, mark the pages dirty
|
||||
+ * again.
|
||||
+ */
|
||||
+ for ( i = 0; i < (1UL << page_order); ++i )
|
||||
+ {
|
||||
+ p2m->get_entry(p2m, gfn_add(gfn, i), &t, &a, 0, NULL, NULL);
|
||||
+ if ( !p2m_is_hole(t) && !p2m_is_special(t) && !p2m_is_shared(t) )
|
||||
+ {
|
||||
+ set_gpfn_from_mfn(mfn_x(mfn) + i, gfn_x(gfn) + i);
|
||||
+ paging_mark_pfn_dirty(p2m->domain, _pfn(gfn_x(gfn) + i));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1003,13 +1023,8 @@ guest_physmap_add_entry(struct domain *d
|
||||
|
||||
/* Now, actually do the two-way mapping */
|
||||
rc = p2m_set_entry(p2m, gfn, mfn, page_order, t, p2m->default_access);
|
||||
- if ( rc == 0 )
|
||||
+ if ( likely(!rc) )
|
||||
{
|
||||
- pod_lock(p2m);
|
||||
- p2m->pod.entry_count -= pod_count;
|
||||
- BUG_ON(p2m->pod.entry_count < 0);
|
||||
- pod_unlock(p2m);
|
||||
-
|
||||
if ( !p2m_is_grant(t) )
|
||||
{
|
||||
for ( i = 0; i < (1UL << page_order); i++ )
|
||||
@@ -1017,6 +1032,42 @@ guest_physmap_add_entry(struct domain *d
|
||||
gfn_x(gfn_add(gfn, i)));
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ /*
|
||||
+ * The operation may have partially succeeded. For the successful part
|
||||
+ * we need to update M2P and dirty state, while for the failed part we
|
||||
+ * may need to adjust PoD stats as well as undo the earlier M2P update.
|
||||
+ */
|
||||
+ for ( i = 0; i < (1UL << page_order); ++i )
|
||||
+ {
|
||||
+ omfn = p2m->get_entry(p2m, gfn_add(gfn, i), &ot, &a, 0, NULL, NULL);
|
||||
+ if ( p2m_is_pod(ot) )
|
||||
+ {
|
||||
+ BUG_ON(!pod_count);
|
||||
+ --pod_count;
|
||||
+ }
|
||||
+ else if ( mfn_eq(omfn, mfn_add(mfn, i)) && ot == t &&
|
||||
+ a == p2m->default_access && !p2m_is_grant(t) )
|
||||
+ {
|
||||
+ set_gpfn_from_mfn(mfn_x(omfn), gfn_x(gfn) + i);
|
||||
+ paging_mark_pfn_dirty(d, _pfn(gfn_x(gfn) + i));
|
||||
+ }
|
||||
+ else if ( p2m_is_ram(ot) && !p2m_is_paged(ot) )
|
||||
+ {
|
||||
+ ASSERT(mfn_valid(omfn));
|
||||
+ set_gpfn_from_mfn(mfn_x(omfn), gfn_x(gfn) + i);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ( pod_count )
|
||||
+ {
|
||||
+ pod_lock(p2m);
|
||||
+ p2m->pod.entry_count -= pod_count;
|
||||
+ BUG_ON(p2m->pod.entry_count < 0);
|
||||
+ pod_unlock(p2m);
|
||||
+ }
|
||||
|
||||
out:
|
||||
p2m_unlock(p2m);
|
||||
@@ -1308,6 +1359,49 @@ static int set_typed_p2m_entry(struct do
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ P2M_DEBUG("set %d %lx %lx\n", gfn_p2mt, gfn_l, mfn_x(mfn));
|
||||
+ rc = p2m_set_entry(p2m, gfn, mfn, order, gfn_p2mt, access);
|
||||
+ if ( unlikely(rc) )
|
||||
+ {
|
||||
+ gdprintk(XENLOG_ERR, "p2m_set_entry: %#lx:%u -> %d (0x%"PRI_mfn")\n",
|
||||
+ gfn_l, order, rc, mfn_x(mfn));
|
||||
+
|
||||
+ /*
|
||||
+ * The operation may have partially succeeded. For the successful part
|
||||
+ * we need to update PoD stats, M2P, and dirty state.
|
||||
+ */
|
||||
+ if ( order != PAGE_ORDER_4K )
|
||||
+ {
|
||||
+ unsigned long i;
|
||||
+
|
||||
+ for ( i = 0; i < (1UL << order); ++i )
|
||||
+ {
|
||||
+ p2m_type_t t;
|
||||
+ mfn_t cmfn = p2m->get_entry(p2m, gfn_add(gfn, i), &t, &a, 0,
|
||||
+ NULL, NULL);
|
||||
+
|
||||
+ if ( !mfn_eq(cmfn, mfn_add(mfn, i)) || t != gfn_p2mt ||
|
||||
+ a != access )
|
||||
+ continue;
|
||||
+
|
||||
+ if ( p2m_is_ram(ot) )
|
||||
+ {
|
||||
+ ASSERT(mfn_valid(mfn_add(omfn, i)));
|
||||
+ set_gpfn_from_mfn(mfn_x(omfn) + i, INVALID_M2P_ENTRY);
|
||||
+ }
|
||||
+#ifdef CONFIG_HVM
|
||||
+ else if ( p2m_is_pod(ot) )
|
||||
+ {
|
||||
+ pod_lock(p2m);
|
||||
+ BUG_ON(!p2m->pod.entry_count);
|
||||
+ --p2m->pod.entry_count;
|
||||
+ pod_unlock(p2m);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
else if ( p2m_is_ram(ot) )
|
||||
{
|
||||
unsigned long i;
|
||||
@@ -1318,12 +1412,6 @@ static int set_typed_p2m_entry(struct do
|
||||
set_gpfn_from_mfn(mfn_x(omfn) + i, INVALID_M2P_ENTRY);
|
||||
}
|
||||
}
|
||||
-
|
||||
- P2M_DEBUG("set %d %lx %lx\n", gfn_p2mt, gfn_l, mfn_x(mfn));
|
||||
- rc = p2m_set_entry(p2m, gfn, mfn, order, gfn_p2mt, access);
|
||||
- if ( rc )
|
||||
- gdprintk(XENLOG_ERR, "p2m_set_entry: %#lx:%u -> %d (0x%"PRI_mfn")\n",
|
||||
- gfn_l, order, rc, mfn_x(mfn));
|
||||
#ifdef CONFIG_HVM
|
||||
else if ( p2m_is_pod(ot) )
|
||||
{
|
||||
Loading…
Add table
Add a link
Reference in a new issue